diff --git a/angular.json b/angular.json index 753ba39d..9e543265 100644 --- a/angular.json +++ b/angular.json @@ -3,52 +3,6 @@ "version": 1, "newProjectRoot": "projects", "projects": { - "wave-core": { - "projectType": "library", - "schematics": { - "@schematics/angular:component": { - "changeDetection": "OnPush", - "inlineStyle": false, - "inlineTemplate": false, - "prefix": "wave", - "style": "scss" - }, - "@schematics/angular:directive": { - "prefix": "wave" - } - }, - "root": "projects/wave-core", - "sourceRoot": "projects/wave-core/src", - "prefix": "wave", - "architect": { - "build": { - "builder": "@angular-devkit/build-ng-packagr:build", - "options": { - "tsConfig": "projects/wave-core/tsconfig.lib.json", - "project": "projects/wave-core/ng-package.json" - }, - "configurations": { - "production": { - "tsConfig": "projects/wave-core/tsconfig.lib.prod.json" - } - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "projects/wave-core/src/test.ts", - "tsConfig": "projects/wave-core/tsconfig.spec.json", - "karmaConfig": "projects/wave-core/karma.conf.js" - } - }, - "lint": { - "builder": "@angular-eslint/builder:lint", - "options": { - "lintFilePatterns": ["projects/wave-core/**/*.ts", "projects/wave-core/**/*.html"] - } - } - } - }, "wave-core-new": { "projectType": "library", "schematics": { @@ -68,7 +22,7 @@ "prefix": "wave", "architect": { "build": { - "builder": "@angular-devkit/build-ng-packagr:build", + "builder": "@angular-devkit/build-angular:ng-packagr", "options": { "tsConfig": "projects/wave-core-new/tsconfig.lib.json", "project": "projects/wave-core-new/ng-package.json" @@ -95,133 +49,6 @@ } } }, - "wave-app": { - "projectType": "application", - "schematics": { - "@schematics/angular:component": { - "changeDetection": "OnPush", - "inlineStyle": false, - "inlineTemplate": false, - "prefix": "wave-app", - "style": "scss" - }, - "@schematics/angular:directive": { - "prefix": "wave-app" - } - }, - "root": "projects/wave-app", - "sourceRoot": "projects/wave-app/src", - "prefix": "wave-app", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "allowedCommonJsDependencies": ["dagre-d3", "pbf"], - "outputPath": "dist/wave-app", - "index": "projects/wave-app/src/index.html", - "main": "projects/wave-app/src/main.ts", - "polyfills": "projects/wave-app/src/polyfills.ts", - "tsConfig": "projects/wave-app/tsconfig.app.json", - "aot": true, - "assets": [ - "projects/wave-app/src/favicon.ico", - "projects/wave-app/src/assets", - { - "glob": "**/*", - "input": "dist/wave-core/assets", - "output": "assets" - } - ], - "styles": [ - "projects/wave-app/src/styles.scss", - "dist/wave-core/assets/fonts/roboto/roboto.css", - "dist/wave-core/assets/fonts/pacifico/pacifico.css", - "dist/wave-core/assets/fonts/material-design-icons/material-icons.css", - "node_modules/codemirror/lib/codemirror.css", - "node_modules/ol/ol.css" - ], - "scripts": [] - }, - "configurations": { - "production": { - "fileReplacements": [ - { - "replace": "projects/wave-app/src/environments/environment.ts", - "with": "projects/wave-app/src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "extractCss": true, - "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "5mb", - "maximumError": "10mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "6kb", - "maximumError": "10kb" - } - ] - } - } - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "wave-app:build" - }, - "configurations": { - "production": { - "browserTarget": "wave-app:build:production" - } - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "wave-app:build" - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "projects/wave-app/src/test.ts", - "polyfills": "projects/wave-app/src/polyfills.ts", - "tsConfig": "projects/wave-app/tsconfig.spec.json", - "karmaConfig": "projects/wave-app/karma.conf.js", - "assets": ["projects/wave-app/src/favicon.ico", "projects/wave-app/src/assets"], - "styles": ["projects/wave-app/src/styles.scss"], - "scripts": [] - } - }, - "lint": { - "builder": "@angular-eslint/builder:lint", - "options": { - "lintFilePatterns": ["projects/wave-app/**/*.ts", "projects/wave-app/**/*.html"] - } - }, - "e2e": { - "builder": "@angular-devkit/build-angular:protractor", - "options": { - "protractorConfig": "projects/wave-app/e2e/protractor.conf.js", - "devServerTarget": "wave-app:serve" - }, - "configurations": { - "production": { - "devServerTarget": "wave-app:serve:production" - } - } - } - } - }, "geoengine-app": { "projectType": "application", "schematics": { @@ -280,7 +107,6 @@ "optimization": true, "outputHashing": "all", "sourceMap": false, - "extractCss": true, "namedChunks": false, "extractLicenses": true, "vendorChunk": false, @@ -407,7 +233,6 @@ "optimization": true, "outputHashing": "all", "sourceMap": false, - "extractCss": true, "namedChunks": false, "extractLicenses": true, "vendorChunk": false, @@ -475,261 +300,7 @@ } } } - }, - "gfbio-app": { - "projectType": "application", - "schematics": { - "@schematics/angular:component": { - "changeDetection": "OnPush", - "inlineStyle": false, - "inlineTemplate": false, - "prefix": "wave-gfbio", - "style": "scss" - }, - "@schematics/angular:directive": { - "prefix": "wave-gfbio" - } - }, - "root": "projects/gfbio-app", - "sourceRoot": "projects/gfbio-app/src", - "prefix": "wave-gfbio", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "allowedCommonJsDependencies": ["dagre-d3", "pbf"], - "outputPath": "dist/gfbio-app", - "index": "projects/gfbio-app/src/index.html", - "main": "projects/gfbio-app/src/main.ts", - "polyfills": "projects/gfbio-app/src/polyfills.ts", - "tsConfig": "projects/gfbio-app/tsconfig.app.json", - "aot": true, - "assets": [ - "projects/gfbio-app/src/favicon.ico", - "projects/gfbio-app/src/assets", - { - "glob": "**/*", - "input": "dist/wave-core/assets", - "output": "assets" - } - ], - "styles": [ - "projects/gfbio-app/src/styles.scss", - "dist/wave-core/assets/fonts/roboto/roboto.css", - "dist/wave-core/assets/fonts/pacifico/pacifico.css", - "dist/wave-core/assets/fonts/material-design-icons/material-icons.css", - "node_modules/codemirror/lib/codemirror.css", - "node_modules/ol/ol.css" - ], - "scripts": [] - }, - "configurations": { - "production": { - "fileReplacements": [ - { - "replace": "projects/gfbio-app/src/environments/environment.ts", - "with": "projects/gfbio-app/src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "extractCss": true, - "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "5mb", - "maximumError": "10mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "6kb", - "maximumError": "10kb" - } - ] - } - } - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "gfbio-app:build" - }, - "configurations": { - "production": { - "browserTarget": "gfbio-app:build:production" - } - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "gfbio-app:build" - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "projects/gfbio-app/src/test.ts", - "polyfills": "projects/gfbio-app/src/polyfills.ts", - "tsConfig": "projects/gfbio-app/tsconfig.spec.json", - "karmaConfig": "projects/gfbio-app/karma.conf.js", - "assets": ["projects/gfbio-app/src/favicon.ico", "projects/gfbio-app/src/assets"], - "styles": ["projects/gfbio-app/src/styles.scss"], - "scripts": [] - } - }, - "lint": { - "builder": "@angular-eslint/builder:lint", - "options": { - "lintFilePatterns": ["projects/gfbio-app/**/*.ts", "projects/gfbio-app/**/*.html"] - } - }, - "e2e": { - "builder": "@angular-devkit/build-angular:protractor", - "options": { - "protractorConfig": "projects/gfbio-app/e2e/protractor.conf.js", - "devServerTarget": "gfbio-app:serve" - }, - "configurations": { - "production": { - "devServerTarget": "gfbio-app:serve:production" - } - } - } - } - }, - "nature40-app": { - "projectType": "application", - "schematics": { - "@schematics/angular:component": { - "changeDetection": "OnPush", - "inlineStyle": false, - "inlineTemplate": false, - "prefix": "wave-nature40", - "style": "scss" - }, - "@schematics/angular:directive": { - "prefix": "wave-nature40" - } - }, - "root": "projects/nature40-app", - "sourceRoot": "projects/nature40-app/src", - "prefix": "wave-nature40", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "allowedCommonJsDependencies": ["dagre-d3", "pbf"], - "outputPath": "dist/nature40-app", - "index": "projects/nature40-app/src/index.html", - "main": "projects/nature40-app/src/main.ts", - "polyfills": "projects/nature40-app/src/polyfills.ts", - "tsConfig": "projects/nature40-app/tsconfig.app.json", - "aot": true, - "assets": [ - "projects/nature40-app/src/favicon.ico", - "projects/nature40-app/src/assets", - { - "glob": "**/*", - "input": "dist/wave-core/assets", - "output": "assets" - } - ], - "styles": [ - "projects/nature40-app/src/styles.scss", - "dist/wave-core/assets/fonts/roboto/roboto.css", - "dist/wave-core/assets/fonts/pacifico/pacifico.css", - "dist/wave-core/assets/fonts/material-design-icons/material-icons.css", - "node_modules/codemirror/lib/codemirror.css", - "node_modules/ol/ol.css" - ], - "scripts": [] - }, - "configurations": { - "production": { - "fileReplacements": [ - { - "replace": "projects/nature40-app/src/environments/environment.ts", - "with": "projects/nature40-app/src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "extractCss": true, - "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "5mb", - "maximumError": "10mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "6kb", - "maximumError": "10kb" - } - ] - } - } - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "nature40-app:build" - }, - "configurations": { - "production": { - "browserTarget": "nature40-app:build:production" - } - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "nature40-app:build" - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "projects/nature40-app/src/test.ts", - "polyfills": "projects/nature40-app/src/polyfills.ts", - "tsConfig": "projects/nature40-app/tsconfig.spec.json", - "karmaConfig": "projects/nature40-app/karma.conf.js", - "assets": ["projects/nature40-app/src/favicon.ico", "projects/nature40-app/src/assets"], - "styles": ["projects/nature40-app/src/styles.scss"], - "scripts": [] - } - }, - "lint": { - "builder": "@angular-eslint/builder:lint", - "options": { - "lintFilePatterns": ["projects/nature40-app/**/*.ts", "projects/nature40-app/**/*.html"] - } - }, - "e2e": { - "builder": "@angular-devkit/build-angular:protractor", - "options": { - "protractorConfig": "projects/nature40-app/e2e/protractor.conf.js", - "devServerTarget": "nature40-app:serve" - }, - "configurations": { - "production": { - "devServerTarget": "nature40-app:serve:production" - } - } - } - } } }, - "defaultProject": "wave-core" + "defaultProject": "wave-core-new" } diff --git a/custom_typings/darge-d3.d.ts b/custom_typings/darge-d3.d.ts deleted file mode 100644 index 0a4ed26d..00000000 --- a/custom_typings/darge-d3.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -// dagre-d3.d.ts -// Copied from existing type definition @types/dagre-d3, with some modification -declare module 'dagre-d3' { - import * as d3 from 'd3'; - import * as dagre from 'dagre'; - export const render: new () => Render; - export const intersect: { - [shapeName: string]: ( - node: dagre.Node, - points: Array<{}>, - point: any - ) => void; - }; - - export interface Render { - arrows(): { - [arrowStyleName: string]: ( - parent: d3.Selection, - id: string, - edge: dagre.Edge, - type: string - ) => void; - }; - - ( - selection: d3.Selection, - g: dagre.graphlib.Graph - ): void; - - shapes(): { - [shapeStyleName: string]: ( - parent: d3.Selection, - bbox: any, - node: dagre.Node - ) => void; - }; - } -} diff --git a/custom_typings/proj4.d.ts b/custom_typings/proj4.d.ts deleted file mode 100644 index 53226c36..00000000 --- a/custom_typings/proj4.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -declare namespace Proj { - - interface Transformer { - forward: (p: Point) => Point; - inverse: (p: Point) => Point; - } - - class Point { - x: number; - y: number; - constructor(x: number, y: number); - } - - function Proj(a: any, b: any): Transformer; - - export function defs(name: string): any; - export function defs(name: string, def: string): void; - export function transform(from: any, to: any, pt: Point): Point; - export function parse(sr: string): any; - -} - -declare module "proj4" { - export = Proj; -} diff --git a/package.json b/package.json index d88e3976..ca6c803d 100644 --- a/package.json +++ b/package.json @@ -4,27 +4,20 @@ "license": "MIT", "scripts": { "ng": "ng", - "prettier": "prettier", - "start": "ng serve", - "build": "npm run build-prod:core && npm run build-prod:wave && npm run build-prod:gfbio && npm run build-prod:nature40", - "check": "prettier --check . && ng lint wave-core-new && ng lint geoengine-app && ng lint data-atlas-app", - "ci-core": "ng build --prod wave-core-new", - "serve:wave": "ng serve wave-app --proxy-config proxy.conf.json", + "build": "npm run build-prod:core && npm run build-apps", + "build:core": "ng build wave-core-new", + "build-watch:core": "ng build wave-core-new --watch", + "build-prod:core": "ng build --prod wave-core-new", + "build-apps": "npm run build-prod:geoengine && npm run build-prod:data-atlas", "serve:geoengine": "ng serve geoengine-app --proxy-config proxy-geoengine.conf.json", "serve:data-atlas": "ng serve data-atlas-app --proxy-config proxy-data-atlas.conf.json", - "serve:gfbio": "ng serve gfbio-app --proxy-config proxy.conf.json", - "serve:nature40": "ng serve nature40-app --proxy-config proxy.conf.json", - "build:core": "ng build wave-core", - "build-watch:core": "ng build wave-core --watch", - "build:core-new": "ng build wave-core-new", - "build-watch:core-new": "ng build wave-core-new --watch", - "build-prod:core": "ng build --prod wave-core", - "build-prod:wave": "ng build --prod wave-app", - "build-prod:gfbio": "ng build --prod gfbio-app", - "build-prod:nature40": "ng build --prod nature40-app", + "build-prod:geoengine": "ng build --prod geoengine-app", + "build-prod:data-atlas": "ng build --prod data-atlas-app", "publish:core:patch": "version=patch scripts/publish-to-github.sh", "publish:core:minor": "version=minor scripts/publish-to-github.sh", "publish:core:major": "version=major scripts/publish-to-github.sh", + "prettier": "prettier", + "check": "prettier --check . && ng lint", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", @@ -32,17 +25,17 @@ }, "private": true, "dependencies": { - "@angular/animations": "~10.1.5", - "@angular/cdk": "~10.2.4", - "@angular/common": "~10.1.5", - "@angular/compiler": "~10.1.5", - "@angular/core": "~10.1.5", - "@angular/flex-layout": "~10.0.0-beta.32", - "@angular/forms": "~10.1.5", - "@angular/material": "~10.2.4", - "@angular/platform-browser": "~10.1.5", - "@angular/platform-browser-dynamic": "~10.1.5", - "@angular/router": "~10.1.5", + "@angular/animations": "~11.2.7", + "@angular/cdk": "~11.2.6", + "@angular/common": "~11.2.7", + "@angular/compiler": "~11.2.7", + "@angular/core": "~11.2.7", + "@angular/flex-layout": "~11.0.0-beta.33", + "@angular/forms": "~11.2.7", + "@angular/material": "~11.2.6", + "@angular/platform-browser": "~11.2.7", + "@angular/platform-browser-dynamic": "~11.2.7", + "@angular/router": "~11.2.7", "codemirror": "~5.58.1", "d3": "~6.2.0", "dagre": "~0.8.5", @@ -63,40 +56,40 @@ "zone.js": "~0.10.3" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.1002.2", - "@angular-devkit/build-ng-packagr": "~0.1002.2", - "@angular-eslint/builder": "1.2.0", - "@angular-eslint/eslint-plugin": "1.2.0", - "@angular-eslint/eslint-plugin-template": "1.2.0", - "@angular-eslint/schematics": "1.2.0", - "@angular-eslint/template-parser": "1.2.0", - "@angular/cli": "~10.2.3", - "@angular/compiler-cli": "~10.1.5", - "@angular/language-service": "~10.1.5", + "@angular-devkit/architect": "^0.1102.6", + "@angular-devkit/build-angular": "~0.1102.6", + "@angular-eslint/builder": "^2.0.0", + "@angular-eslint/eslint-plugin": "^2.0.0", + "@angular-eslint/eslint-plugin-template": "^2.0.0", + "@angular-eslint/schematics": "2.0.2", + "@angular-eslint/template-parser": "^2.0.0", + "@angular/cli": "~11.2.6", + "@angular/compiler-cli": "~11.2.7", + "@angular/language-service": "~11.2.7", "@types/codemirror": "~0.0.87", "@types/d3": "~5.16.3", - "@types/jasmine": "~3.5.14", + "@types/jasmine": "~3.6.0", "@types/jasminewd2": "~2.0.3", "@types/node": "^12.11.1", "@types/papaparse": "~4.5.7", - "@typescript-eslint/eslint-plugin": "4.3.0", - "@typescript-eslint/parser": "4.3.0", + "@typescript-eslint/eslint-plugin": "4.16.1", + "@typescript-eslint/parser": "4.16.1", "eslint": "^7.6.0", "eslint-config-prettier": "^8.1.0", "eslint-plugin-import": "2.22.1", "eslint-plugin-jsdoc": "30.7.6", "eslint-plugin-prefer-arrow": "1.2.2", "eslint-plugin-prettier": "^3.3.1", - "jasmine-core": "~3.5.0", - "jasmine-spec-reporter": "~4.2.1", - "karma": "~4.3.0", + "jasmine-core": "~3.6.0", + "jasmine-spec-reporter": "~5.0.0", + "karma": "~6.1.0", "karma-chrome-launcher": "~3.1.0", "karma-coverage-istanbul-reporter": "~2.1.0", - "karma-jasmine": "~2.0.1", - "karma-jasmine-html-reporter": "^1.5.4", - "ng-packagr": "^10.1.0", + "karma-jasmine": "~4.0.0", + "karma-jasmine-html-reporter": "^1.5.0", + "ng-packagr": "~11.1.0", "prettier": "2.2.1", - "protractor": "~5.4.3", + "protractor": "~7.0.0", "ts-node": "~8.3.0", "typescript": "~4.0.3" } diff --git a/projects/geoengine-app/src/app/app.component.ts b/projects/geoengine-app/src/app/app.component.ts index 0465834c..8a395e04 100644 --- a/projects/geoengine-app/src/app/app.component.ts +++ b/projects/geoengine-app/src/app/app.component.ts @@ -18,7 +18,7 @@ import {MatSidenav} from '@angular/material/sidenav'; import {MatTabGroup} from '@angular/material/tabs'; import { AddDataComponent, - AddDataListButton, + AddDataButton, Layer, SidenavContainerComponent, LayoutService, @@ -41,7 +41,6 @@ import { import {DomSanitizer} from '@angular/platform-browser'; import {ActivatedRoute} from '@angular/router'; import {AppConfig} from './app-config.service'; -import {MockLayersComponent} from './mock-layers/mock-layers.component'; @Component({ selector: 'wave-app-root', @@ -190,15 +189,11 @@ export class AppComponent implements OnInit, AfterViewInit { return {component: AddDataComponent, config: {buttons: AppComponent.createAddDataListButtons()}}; } - private static createAddDataListButtons(): Array { + private static createAddDataListButtons(): Array { return [ AddDataComponent.createDataSetListButton(), - { - name: 'Mock data', - description: 'Mock data sets', - iconSrc: AddDataComponent.createIconDataUrl('mock'), - sidenavConfig: {component: MockLayersComponent, keepParent: true}, - }, + AddDataComponent.createUploadButton(), + // SourceOperatorListComponent.createDrawFeaturesButton(), // ...SourceOperatorListComponent.createCustomFeaturesButtons(), // { diff --git a/projects/gfbio-app/.eslintrc.json b/projects/gfbio-app/.eslintrc.json deleted file mode 100644 index 7ddd2178..00000000 --- a/projects/gfbio-app/.eslintrc.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": [ - "projects/gfbio-app/tsconfig.app.json", - "projects/gfbio-app/tsconfig.spec.json", - "projects/gfbio-app/e2e/tsconfig.json" - ], - "createDefaultProgram": true - }, - "rules": {} - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/gfbio-app/browserslist b/projects/gfbio-app/browserslist deleted file mode 100644 index 80848532..00000000 --- a/projects/gfbio-app/browserslist +++ /dev/null @@ -1,12 +0,0 @@ -# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. -# For additional information regarding the format and rule options, please see: -# https://github.com/browserslist/browserslist#queries - -# You can see what browsers were selected by your queries by running: -# npx browserslist - -> 0.5% -last 2 versions -Firefox ESR -not dead -not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/projects/gfbio-app/e2e/protractor.conf.js b/projects/gfbio-app/e2e/protractor.conf.js deleted file mode 100644 index bf4376ef..00000000 --- a/projects/gfbio-app/e2e/protractor.conf.js +++ /dev/null @@ -1,30 +0,0 @@ -// @ts-check -// Protractor configuration file, see link for more information -// https://github.com/angular/protractor/blob/master/lib/config.ts - -const {SpecReporter} = require('jasmine-spec-reporter'); - -/** - * @type { import("protractor").Config } - */ -exports.config = { - allScriptsTimeout: 11000, - specs: ['./src/**/*.e2e-spec.ts'], - capabilities: { - browserName: 'chrome', - }, - directConnect: true, - baseUrl: 'http://localhost:4200/', - framework: 'jasmine', - jasmineNodeOpts: { - showColors: true, - defaultTimeoutInterval: 30000, - print: function () {}, - }, - onPrepare() { - require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json'), - }); - jasmine.getEnv().addReporter(new SpecReporter({spec: {displayStacktrace: true}})); - }, -}; diff --git a/projects/gfbio-app/e2e/src/app.e2e-spec.ts b/projects/gfbio-app/e2e/src/app.e2e-spec.ts deleted file mode 100644 index d3642324..00000000 --- a/projects/gfbio-app/e2e/src/app.e2e-spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {AppPage} from './app.po'; -import {browser, logging} from 'protractor'; - -describe('workspace-project App', () => { - let page: AppPage; - - beforeEach(() => { - page = new AppPage(); - }); - - it('should display welcome message', () => { - page.navigateTo(); - expect(page.getTitleText()).toEqual('gfbio-app app is running!'); - }); - - afterEach(async () => { - // Assert that there are no errors emitted from the browser - const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain( - jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry), - ); - }); -}); diff --git a/projects/gfbio-app/e2e/src/app.po.ts b/projects/gfbio-app/e2e/src/app.po.ts deleted file mode 100644 index e11ba071..00000000 --- a/projects/gfbio-app/e2e/src/app.po.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {browser, by, element} from 'protractor'; - -export class AppPage { - navigateTo(): Promise { - return browser.get(browser.baseUrl) as Promise; - } - - getTitleText(): Promise { - return element(by.css('wave-gfbio-root .content span')).getText() as Promise; - } -} diff --git a/projects/gfbio-app/e2e/tsconfig.json b/projects/gfbio-app/e2e/tsconfig.json deleted file mode 100644 index 3d39212b..00000000 --- a/projects/gfbio-app/e2e/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "outDir": "../../../out-tsc/e2e", - "module": "commonjs", - "target": "es5", - "types": ["jasmine", "jasminewd2", "node"] - } -} diff --git a/projects/gfbio-app/karma.conf.js b/projects/gfbio-app/karma.conf.js deleted file mode 100644 index ebdcbba3..00000000 --- a/projects/gfbio-app/karma.conf.js +++ /dev/null @@ -1,32 +0,0 @@ -// Karma configuration file, see link for more information -// https://karma-runner.github.io/1.0/config/configuration-file.html - -module.exports = function (config) { - config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], - plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage-istanbul-reporter'), - require('@angular-devkit/build-angular/plugins/karma'), - ], - client: { - clearContext: false, // leave Jasmine Spec Runner output visible in browser - }, - coverageIstanbulReporter: { - dir: require('path').join(__dirname, '../../coverage/gfbio-app'), - reports: ['html', 'lcovonly', 'text-summary'], - fixWebpackSourcePaths: true, - }, - reporters: ['progress', 'kjhtml'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome'], - singleRun: false, - restartOnFileChange: true, - }); -}; diff --git a/projects/gfbio-app/src/app-theme.scss b/projects/gfbio-app/src/app-theme.scss deleted file mode 100644 index 91c8fbc7..00000000 --- a/projects/gfbio-app/src/app-theme.scss +++ /dev/null @@ -1,82 +0,0 @@ -@import '~@angular/material/theming'; - -// Material Base Styles -@include mat-core(); - -// Define Colors -$gfbio-darkblue: ( - 50: #e7ebf4, - 100: #c2cee3, - 200: #99add1, - 300: #708cbf, - 400: #5273b1, - 500: #335aa3, - 600: #2e529b, - 700: #274891, - 800: #203f88, - 900: #142e77, - A100: #adc0ff, - A200: #7a98ff, - A400: #4770ff, - A700: #2e5dff, - contrast: ( - 50: $black-87-opacity, - 100: $black-87-opacity, - 200: $black-87-opacity, - 300: $black-87-opacity, - 400: $white-87-opacity, - 500: $white-87-opacity, - 600: $white-87-opacity, - 700: $white-87-opacity, - 800: $white-87-opacity, - 900: $white-87-opacity, - A100: $black-87-opacity, - A200: $black-87-opacity, - A400: $white-87-opacity, - A700: $white-87-opacity, - ), -); - -$gfbio-green: ( - 50: #f0f6e9, - 100: #d9e8c8, - 200: #c0d9a4, - 300: #a7c97f, - 400: #94be63, - 500: #81b248, - 600: #79ab41, - 700: #6ea238, - 800: #649930, - 900: #518a21, - A100: #dfffc7, - A200: #c2ff94, - A400: #a5ff61, - A700: #97ff47, - contrast: ( - 50: $black-87-opacity, - 100: $black-87-opacity, - 200: $black-87-opacity, - 300: $black-87-opacity, - 400: $black-87-opacity, - 500: $black-87-opacity, - 600: $black-87-opacity, - 700: $black-87-opacity, - 800: $white-87-opacity, - 900: $white-87-opacity, - A100: $black-87-opacity, - A200: $black-87-opacity, - A400: $black-87-opacity, - A700: $black-87-opacity, - ), -); - -// Define App Theme -$wave-app-primary: mat-palette($gfbio-darkblue); -$wave-app-accent: mat-palette($gfbio-green, A200, A100, A400); -$wave-app-warn: mat-palette($mat-red); - -// Create the theme object (a Sass map containing all of the palettes). -$wave-app-theme: mat-light-theme($wave-app-primary, $wave-app-accent, $wave-app-warn); - -// Apply Angular Material Mixin to Color Theme -@include angular-material-theme($wave-app-theme); diff --git a/projects/gfbio-app/src/app/app-config.service.ts b/projects/gfbio-app/src/app/app-config.service.ts deleted file mode 100644 index 58654636..00000000 --- a/projects/gfbio-app/src/app/app-config.service.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {Injectable} from '@angular/core'; -import {mergeDeep} from 'immutable'; -import {Config, WaveConfigStructure, WAVE_DEFAULT_CONFIG} from 'wave-core'; - -interface Gfbio { - readonly LIFERAY_PORTAL_URL: string; - readonly SSO: SSO; -} - -interface SSO { - URL: string; - CLIENT_ID: string; - SCOPE: string; -} - -interface AppConfigStructure extends WaveConfigStructure { - readonly GFBIO: Gfbio; -} - -const APP_CONFIG_DEFAULTS = mergeDeep(WAVE_DEFAULT_CONFIG, { - GFBIO: { - LIFERAY_PORTAL_URL: 'https://dev.gfbio.org/', - SSO: { - URL: 'https://sso.gfbio.org/simplesaml/module.php/oidc/authorize.php', - CLIENT_ID: '_d6a8e839d7694e173683f2377d1669f2b3dd209679', - SCOPE: 'openid email id profile', - }, - }, -}) as AppConfigStructure; - -@Injectable() -export class AppConfig extends Config { - protected config: AppConfigStructure; - - get GFBIO(): Gfbio { - return this.config.GFBIO; - } - - load(): Promise { - return super.load(APP_CONFIG_DEFAULTS); - } -} diff --git a/projects/gfbio-app/src/app/app.component.html b/projects/gfbio-app/src/app/app.component.html deleted file mode 100644 index adf2336f..00000000 --- a/projects/gfbio-app/src/app/app.component.html +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - -
- - - - - - - - - - - - - - - - -
-
- - - - -
Data Table
-
- - -
- - -
Citations
-
- - -
-
-
-
diff --git a/projects/gfbio-app/src/app/app.component.scss b/projects/gfbio-app/src/app/app.component.scss deleted file mode 100644 index a76ed4e8..00000000 --- a/projects/gfbio-app/src/app/app.component.scss +++ /dev/null @@ -1,135 +0,0 @@ -wave-navigation { - z-index: 10; -} - -wave-layer-list { - position: absolute; - z-index: 2; - width: 16vw; - min-width: 200px; - left: 0; - top: 0; - background-color: rgba(255, 255, 255, 0.87); - border-bottom-right-radius: 2px; -} - -.time-container { - position: absolute; - left: 16vw; - right: 16vw; - - wave-ticker-interaction, - wave-small-time-interaction, - wave-zoom-handles { - background-color: rgba(255, 255, 255, 0.87); - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; - z-index: 3; - } - - .back-button { - z-index: 3; - - border-radius: 0 0 2px 2px; - margin-left: 1rem; - - padding: 0.2rem 1rem; - - background-color: rgba(255, 255, 255, 0.87); - - span { - margin: 0 0.5rem; - } - - img { - height: 1.8rem; - vertical-align: middle; - } - } -} - -:host ::ng-deep .mat-sidenav-content { - overflow: hidden; -} - -.top-container { - z-index: 1; -} - -.mid-container { - z-index: 0; - position: relative; -} - -.bottom-container { - position: relative; - z-index: 1; - - min-height: 3rem; - @media (max-width: 600px) and (orientation: portrait) { - min-height: 2.5rem; - } - @media (max-width: 960px) and (orientation: landscape) { - min-height: 2rem; - } - - .toggle { - position: absolute; - z-index: 1; - padding: 0; - min-width: 3rem; - width: 3rem; - height: 3rem; - @media (max-width: 600px) and (orientation: portrait) { - min-width: 2.5rem; - width: 2.5rem; - height: 2.5rem; - } - @media (max-width: 960px) and (orientation: landscape) { - min-width: 2rem; - width: 2rem; - height: 2rem; - } - } - - ::ng-deep .mat-tab-label-container { - margin-left: 3rem; - @media (max-width: 600px) and (orientation: portrait) { - margin-left: 2.5rem; - } - @media (max-width: 960px) and (orientation: landscape) { - margin-left: 2rem; - } - } - - @media (max-width: 960px) and (orientation: landscape) { - ::ng-deep mat-tab-header { - height: 2rem; - } - ::ng-deep .mat-tab-label { - line-height: 2rem; - } - } - @media (max-width: 600px) and (orientation: portrait) { - ::ng-deep mat-tab-header { - height: 2.5rem; - } - ::ng-deep .mat-tab-label { - line-height: 2.5rem; - } - } -} - -.bottom-container.small { - max-height: 3rem !important; - @media (max-width: 600px) and (orientation: portrait) { - max-height: 2.5rem !important; - } - @media (max-width: 960px) and (orientation: landscape) { - max-height: 2rem !important; - } - - ::ng-deep mat-tab-header { - border: 0; - } -} diff --git a/projects/gfbio-app/src/app/app.component.ts b/projects/gfbio-app/src/app/app.component.ts deleted file mode 100644 index 841d636f..00000000 --- a/projects/gfbio-app/src/app/app.component.ts +++ /dev/null @@ -1,488 +0,0 @@ -import {Observable, BehaviorSubject, of as observableOf, from as observableFrom, combineLatest, partition} from 'rxjs'; -import {toArray, map, tap, first, mergeMap, filter} from 'rxjs/operators'; - -import { - AfterViewInit, - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - HostListener, - Inject, - OnInit, - ViewChild, - ViewContainerRef, -} from '@angular/core'; -import {DomSanitizer} from '@angular/platform-browser'; -import {ActivatedRoute, Router} from '@angular/router'; - -import {MatDialog} from '@angular/material/dialog'; -import {MatIconRegistry} from '@angular/material/icon'; -import {MatSidenav} from '@angular/material/sidenav'; -import {MatTabGroup} from '@angular/material/tabs'; - -import { - Layer, - SidenavContainerComponent, - VectorLayer, - MapContainerComponent, - AbstractSymbology, - LayerService, - LayoutService, - ProjectService, - UserService, - StorageService, - RandomColorService, - MappingQueryService, - NotificationService, - MapService, - Config, - ResultTypes, - PointSymbology, - VectorSymbology, - PlotListComponent, - UnexpectedResultType, - Operator, - AbstractVectorSymbology, - WorkflowParameterChoiceDialogComponent, - NavigationButton, - SourceOperatorListComponent, - NavigationComponent, - OperatorListComponent, - TimeConfigComponent, - WorkspaceSettingsComponent, - SourceOperatorListButton, - GFBioSourceType, - GbifOperatorComponent, - OperatorListButtonGroups, - SidenavConfig, -} from 'wave-core'; - -import {AppConfig} from './app-config.service'; -import {GFBioMappingQueryService} from './queries/mapping-query.service'; -import {GFBioUserService} from './users/user.service'; -import { - BasketAvailability, - BasketResult, - IBasketGroupedAbcdResult, - IBasketPangaeaResult, -} from './operators/dialogs/baskets/gfbio-basket.model'; -import {GroupedAbcdBasketResultComponent} from './operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component'; -import {PangaeaBasketResultComponent} from './operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component'; -import {TerminologyLookupOperatorComponent} from './operators/dialogs/terminology-lookup/terminology-lookup.component'; -import {TerminologyLookupType} from './operators/types/terminology-lookup-type'; -import {LoginComponent} from './login/login.component'; -import {AbcdRepositoryComponent} from './operators/dialogs/abcd-repository/abcd-repository.component'; -import {ABCDSourceType} from './operators/types/abcd-source-type.model'; -import {GfbioBasketsComponent} from './operators/dialogs/baskets/gfbio-baskets.component'; -import {SplashDialogComponent} from './dialogs/splash-dialog/splash-dialog.component'; -import {HelpComponent} from './help/help.component'; -import {Location} from '@angular/common'; - -@Component({ - selector: 'wave-gfbio-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AppComponent implements OnInit, AfterViewInit { - @ViewChild(MapContainerComponent, {static: true}) mapComponent: MapContainerComponent; - @ViewChild(MatTabGroup, {static: true}) bottomTabs: MatTabGroup; - - @ViewChild(MatSidenav, {static: true}) rightSidenav: MatSidenav; - @ViewChild(SidenavContainerComponent, {static: true}) rightSidenavContainer: SidenavContainerComponent; - - readonly ResultTypes = ResultTypes; - readonly LayoutService = LayoutService; - - readonly layersReverse$: Observable>>; - readonly layerListVisible$: Observable; - readonly layerDetailViewVisible$: Observable; - - readonly navigationButtons = this.setupNavigation(); - readonly addAFirstLayerConfig = AppComponent.setupAddDataConfig(); - - middleContainerHeight$: Observable; - bottomContainerHeight$: Observable; - mapIsGrid$: Observable; - - private windowHeight$ = new BehaviorSubject(window.innerHeight); - - constructor( - @Inject(Config) readonly config: AppConfig, - readonly layerService: LayerService, - readonly layoutService: LayoutService, - readonly projectService: ProjectService, - readonly vcRef: ViewContainerRef, // reference used by color picker - @Inject(UserService) private readonly userService: GFBioUserService, - private readonly storageService: StorageService, - private readonly changeDetectorRef: ChangeDetectorRef, - private readonly dialog: MatDialog, - private readonly iconRegistry: MatIconRegistry, - private readonly randomColorService: RandomColorService, - @Inject(MappingQueryService) private readonly mappingQueryService: GFBioMappingQueryService, - private readonly activatedRoute: ActivatedRoute, - private readonly router: Router, - private readonly location: Location, - private readonly notificationService: NotificationService, - private readonly mapService: MapService, - private readonly sanitizer: DomSanitizer, - ) { - this.registerIcons(); - - vcRef.length; // eslint-disable-line @typescript-eslint/no-unused-expressions - - this.storageService.toString(); // just register - - this.layersReverse$ = this.projectService.getLayerStream().pipe(map((layers) => layers.slice(0).reverse())); - - this.layerListVisible$ = this.layoutService.getLayerListVisibilityStream(); - this.layerDetailViewVisible$ = this.layoutService.getLayerDetailViewVisibilityStream(); - } - - private registerIcons() { - this.iconRegistry.addSvgIconInNamespace('vat', 'logo', this.sanitizer.bypassSecurityTrustResourceUrl('assets/vat_logo.svg')); - - // used for navigation - this.iconRegistry.addSvgIcon('cogs', this.sanitizer.bypassSecurityTrustResourceUrl('assets/icons/cogs.svg')); - } - - ngOnInit() { - this.mapService.registerMapComponent(this.mapComponent); - this.mapIsGrid$ = this.mapService.isGrid$; - - this.middleContainerHeight$ = this.layoutService.getMapHeightStream(this.windowHeight$).pipe(tap(() => this.mapComponent.resize())); - this.bottomContainerHeight$ = this.layoutService.getLayerDetailViewStream(this.windowHeight$); - } - - ngAfterViewInit() { - this.layoutService.getSidenavContentComponentStream().subscribe((sidenavConfig) => { - this.rightSidenavContainer.load(sidenavConfig); - if (sidenavConfig) { - this.rightSidenav.open(); - } else { - this.rightSidenav.close(); - } - }); - this.projectService - .getNewPlotStream() - .subscribe(() => this.layoutService.setSidenavContentComponent({component: PlotListComponent})); - - // set the stored tab index - this.layoutService.getLayerDetailViewTabIndexStream().subscribe((tabIndex) => { - if (this.bottomTabs.selectedIndex !== tabIndex) { - this.bottomTabs.selectedIndex = tabIndex; - setTimeout(() => this.changeDetectorRef.markForCheck()); - } - }); - - // show splash screen - if (this.userService.shouldShowIntroductoryPopup()) { - setTimeout(() => { - this.dialog.open(SplashDialogComponent, {}); - }); - } - - // notify window parent that this component is ready - if (parent !== window) { - parent.postMessage( - { - type: 'STATUS', - status: 'READY', - }, - '*', - ); - } else { - // handle query parameters directly if it is not embedded and using an auto login - this.handleQueryParameters(); - } - } - - setTabIndex(index: number) { - this.layoutService.setLayerDetailViewTabIndex(index); - this.layoutService.setLayerDetailViewVisibility(true); - } - - private setupNavigation(): Array { - return [ - NavigationComponent.createLoginButton(this.userService, this.layoutService, this.config, {component: LoginComponent}), - { - sidenavConfig: AppComponent.setupAddDataConfig(), - icon: 'add', - tooltip: 'Add Data', - }, - { - sidenavConfig: AppComponent.setupOperatorListConfig(), - icon: '', - svgIcon: 'cogs', - tooltip: 'Operators', - }, - { - sidenavConfig: {component: PlotListComponent, config: {operatorsListConfig: AppComponent.setupOperatorListConfig()}}, - icon: 'equalizer', - tooltip: 'Plots', - }, - { - sidenavConfig: {component: TimeConfigComponent}, - icon: 'access_time', - tooltip: 'Time', - }, - { - sidenavConfig: {component: WorkspaceSettingsComponent}, - icon: 'settings', - tooltip: 'Workspace', - }, - { - sidenavConfig: {component: HelpComponent}, - icon: 'help', - tooltip: 'Help', - }, - ]; - } - - private static setupAddDataConfig(): SidenavConfig { - return {component: SourceOperatorListComponent, config: {buttons: AppComponent.createSourceOperatorListButtons()}}; - } - - private static setupOperatorListConfig(): SidenavConfig { - return {component: OperatorListComponent, config: {operators: AppComponent.createOperatorListButtons()}}; - } - - private static createSourceOperatorListButtons(): Array { - return [ - SourceOperatorListComponent.createDataRepositoryButton(), - { - name: 'ABCD Archives', - description: 'Lookup GFBio ABCD archive', - iconSrc: ABCDSourceType.ICON_URL, - sidenavConfig: {component: AbcdRepositoryComponent, keepParent: true}, - }, - { - name: 'GFBio Search Baskets', - description: 'Display your GFBio search results', - icon: 'add_shopping_cart', - sidenavConfig: {component: GfbioBasketsComponent, keepParent: true}, - onlyIfLoggedIn: true, - }, - { - name: 'GFBio Search Baskets', - description: 'Log in to display your GFBio search results', - icon: 'add_shopping_cart', - sidenavConfig: undefined, - onlyIfLoggedOut: true, - }, - SourceOperatorListComponent.createDrawFeaturesButton(), - ...SourceOperatorListComponent.createCustomFeaturesButtons(), - { - name: 'Species Occurrences', - description: 'Query data from GBIF', - iconSrc: GFBioSourceType.ICON_URL, - sidenavConfig: {component: GbifOperatorComponent, keepParent: true}, - }, - SourceOperatorListComponent.createCountryPolygonsButton(), - ]; - } - - private static createOperatorListButtons(): OperatorListButtonGroups { - return [ - {name: 'Mixed', list: OperatorListComponent.DEFAULT_MIXED_OPERATOR_DIALOGS}, - {name: 'Plots', list: OperatorListComponent.DEFAULT_PLOT_OPERATOR_DIALOGS}, - {name: 'Raster', list: OperatorListComponent.DEFAULT_RASTER_OPERATOR_DIALOGS}, - { - name: 'Vector', - list: [ - ...OperatorListComponent.DEFAULT_VECTOR_OPERATOR_DIALOGS, - { - component: TerminologyLookupOperatorComponent, - type: TerminologyLookupType, - description: 'Augment attributes via the GFBio Terminology Service', - }, - ], - }, - ]; - } - - @HostListener('window:resize') - private windowHeight() { - this.windowHeight$.next(window.innerHeight); - } - - private handleQueryParameters() { - // If the GFBio SSO sends a link with `#access_token=…` without starting query params with a `?`, - // it can be necessary to redirect the request to `/#/?access_token=…`. - // This prevents Angular routing from cropping the access token from the URL and use proper routing. - // This could be removed once the GFBio SSO sends proper redirects. - const location_path = this.location.path(true); - if (location_path.startsWith('access_token=')) { - this.location.go('/', location_path); - } - - // Since `initialNavigation=false` in the app module, we have to start it here. - this.router.initialNavigation(); - - this.activatedRoute.queryParamMap.subscribe((params) => { - if (params.has('access_token') && params.get('token_type') === 'Bearer' && params.has('expires_in')) { - this.handleOpenIdConnectAccessToken( - params.get('access_token'), - parseInt(params.get('expires_in'), 10), - params.get('state'), - ); - } else if (params.has('workflow')) { - this.handleWorkflow(params.get('workflow')); - } else if (params.has('gfbioBasketId')) { - this.handleGFBioBasketId(params.get('gfbioBasketId')); - } else if (params.keys.length) { - // FALLBACK - must be last branch - this.notificationService.error(`Unknown URL parameters »${params.keys.join(', ')}«`); - } - }); - } - - private handleOpenIdConnectAccessToken(accessToken: string, _expiresIn: number, state: string | null) { - this.userService - .oidcLogin(accessToken) - .pipe(filter((success) => success)) - .subscribe(() => { - if (state) { - state = decodeURIComponent(state); - this.router.navigateByUrl('?' + state); - } - }); - } - - private handleWorkflow(workflow: string) { - try { - const newLayer = Layer.fromDict(JSON.parse(workflow)); - this.projectService - .getProjectStream() - .pipe(first()) - .subscribe((project) => { - if (project.layers.length > 0) { - // show popup - this.dialog.open(WorkflowParameterChoiceDialogComponent, { - data: { - dialogTitle: 'Workflow URL Parameter', - sourceName: 'URL parameter', - layers: [newLayer], - nonAvailableNames: [], - numberOfLayersInProject: project.layers.length, - }, - }); - } else { - // just add the layer if the layer array is empty - this.projectService.addLayer(newLayer); - } - }); - } catch (error) { - this.notificationService.error(`Invalid Workflow: »${error}«`); - } - } - - private handleGFBioBasketId(gfbioBasketIdString: string) { - if (this.userService.isGuestUser()) { - this.userService.redirectToOidcProvider(`gfbioBasketId=${gfbioBasketIdString}`); - } - - try { - const gfbioBasketId: number = JSON.parse(gfbioBasketIdString); - this.projectService - .getProjectStream() - .pipe(first()) - .subscribe((project) => { - this.gfbioBasketIdToLayers(gfbioBasketId).subscribe( - (importResult: BasketAvailability) => { - // show popup - this.dialog.open(WorkflowParameterChoiceDialogComponent, { - data: { - dialogTitle: 'GFBio Basket Import', - sourceName: 'GFBio Basket', - layers: importResult.availableLayers, - nonAvailableNames: importResult.nonAvailableNames, - numberOfLayersInProject: project.layers.length, - }, - }); - }, - (error) => { - this.notificationService.error(`GFBio Basket Loading Error: »${error}«`); - }, - ); - }); - } catch (error) { - this.notificationService.error(`Invalid GFBio Basket Id: »${error}«`); - } - } - - private gfbioBasketIdToLayers(basketId: number): Observable { - const [availableEntries, nonAvailableEntries]: [Observable, Observable] = partition( - this.mappingQueryService.getGFBioBasket(basketId).pipe(mergeMap((basket) => observableFrom(basket.results))), - (basketResult: BasketResult) => basketResult.available, - ); - - const availableLayers: Observable>> = availableEntries.pipe( - mergeMap((basketResult) => this.gfbioBasketResultToLayer(basketResult)), - toArray(), - ); - - const nonAvailableNames: Observable> = nonAvailableEntries.pipe( - map((basketResult) => basketResult.title), - toArray(), - ); - - return combineLatest([availableLayers, nonAvailableNames]).pipe( - map(([layers, names]: [Array>, Array]) => { - return { - availableLayers: layers, - nonAvailableNames: names, - } as BasketAvailability; - }), - ); - } - - private gfbioBasketResultToLayer(result: BasketResult): Observable> { - let operator$: Observable; - if (result.type === 'abcd_grouped') { - operator$ = this.userService - .getSourceSchemaAbcd() - .pipe( - map((sourceSchema) => - GroupedAbcdBasketResultComponent.createOperatorFromGroupedABCDData( - result as IBasketGroupedAbcdResult, - sourceSchema, - true, - ), - ), - ); - } else if (result.type === 'pangaea') { - operator$ = observableOf(PangaeaBasketResultComponent.createOperatorFromPangaeaData(result as IBasketPangaeaResult)); - } - - return operator$.pipe( - map((operator) => { - let clustered = false; - let symbology; - - switch (operator.resultType) { - case ResultTypes.POINTS: - symbology = PointSymbology.createClusterSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - clustered = true; - break; - case ResultTypes.POLYGONS: - symbology = VectorSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - break; - default: - throw new UnexpectedResultType(); - } - - return new VectorLayer({ - name: result.title, - operator, - symbology, - clustered, - }); - }), - ); - } -} diff --git a/projects/gfbio-app/src/app/app.module.ts b/projects/gfbio-app/src/app/app.module.ts deleted file mode 100644 index ee196772..00000000 --- a/projects/gfbio-app/src/app/app.module.ts +++ /dev/null @@ -1,98 +0,0 @@ -import {APP_INITIALIZER, NgModule} from '@angular/core'; -import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; -import {BrowserModule} from '@angular/platform-browser'; -import {HttpClientModule} from '@angular/common/http'; -import {RouterModule} from '@angular/router'; - -import {AppComponent} from './app.component'; -import { - Config, - LayerService, - LayoutService, - MappingQueryService, - MapService, - NotificationService, - ProjectService, - RandomColorService, - StorageService, - SidenavRef, - UserService, - WaveCoreModule, - OperatorTypeFactory, -} from 'wave-core'; -import {AppConfig} from './app-config.service'; -import {LoginComponent} from './login/login.component'; -import {GFBioUserService} from './users/user.service'; -import {TerminologyLookupType, TerminologyLookupTypeDict} from './operators/types/terminology-lookup-type'; -import {PangaeaSourceType, PangaeaSourceTypeDict} from './operators/types/pangaea-source-type.model'; -import {ABCDSourceType, ABCDSourceTypeDict} from './operators/types/abcd-source-type.model'; -import {AbcdRepositoryComponent} from './operators/dialogs/abcd-repository/abcd-repository.component'; -import {BasketResultGroupByDatasetPipe} from './operators/dialogs/baskets/gfbio-basket.pipe'; -import {GfbioBasketsComponent} from './operators/dialogs/baskets/gfbio-baskets.component'; -import {GroupedAbcdBasketResultComponent} from './operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component'; -import {PangaeaBasketResultComponent} from './operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component'; -import {TerminologyLookupOperatorComponent} from './operators/dialogs/terminology-lookup/terminology-lookup.component'; -import {GFBioMappingQueryService} from './queries/mapping-query.service'; -import {SplashDialogComponent} from './dialogs/splash-dialog/splash-dialog.component'; -import {HelpComponent} from './help/help.component'; - -@NgModule({ - declarations: [ - AppComponent, - AbcdRepositoryComponent, - BasketResultGroupByDatasetPipe, - GfbioBasketsComponent, - GroupedAbcdBasketResultComponent, - LoginComponent, - PangaeaBasketResultComponent, - SplashDialogComponent, - TerminologyLookupOperatorComponent, - HelpComponent, - ], - imports: [ - BrowserAnimationsModule, - BrowserModule, - HttpClientModule, - RouterModule.forRoot([{path: '**', component: AppComponent}], {useHash: true, initialNavigation: 'disabled'}), - WaveCoreModule, - ], - providers: [ - { - provide: APP_INITIALIZER, - useFactory: (config: AppConfig) => () => config.load(), - deps: [Config], - multi: true, - }, - { - provide: APP_INITIALIZER, - useFactory: () => () => setupOperatorTypes(), - deps: [], - multi: true, - }, - LayerService, - LayoutService, - MapService, - NotificationService, - ProjectService, - RandomColorService, - SidenavRef, - StorageService, - {provide: Config, useClass: AppConfig}, - {provide: MappingQueryService, useClass: GFBioMappingQueryService}, - {provide: UserService, useClass: GFBioUserService}, - ], - bootstrap: [AppComponent], -}) -export class AppModule {} - -function setupOperatorTypes(): Promise { - return new Promise((resolve, _reject) => { - OperatorTypeFactory.addType(TerminologyLookupType.TYPE, (dict) => - TerminologyLookupType.fromDict(dict as TerminologyLookupTypeDict), - ); - OperatorTypeFactory.addType(PangaeaSourceType.TYPE, (dict) => PangaeaSourceType.fromDict(dict as PangaeaSourceTypeDict)); - OperatorTypeFactory.addType(ABCDSourceType.TYPE, (dict) => ABCDSourceType.fromDict(dict as ABCDSourceTypeDict)); - - resolve(); - }); -} diff --git a/projects/gfbio-app/src/app/dialogs/splash-dialog/splash-dialog.component.html b/projects/gfbio-app/src/app/dialogs/splash-dialog/splash-dialog.component.html deleted file mode 100644 index b9ba1e0a..00000000 --- a/projects/gfbio-app/src/app/dialogs/splash-dialog/splash-dialog.component.html +++ /dev/null @@ -1,25 +0,0 @@ -VAT - The Visualization, Analysis and Transformation System - -

Biodiversity Data Easily Explored Online

-

Visualize, analyze and transform your biodiversity data in a comfortable online GIS environment! Save and share your workflows!

-

- Have access to collections and biodiversity data centers, international data aggregators and environmental data, and integrate your - own data! -

-

For a detailed introduction, please have a look at our help section!

-
- GFBio -

- VAT is part of the German Federation for Biological Data (GFBio, - www.gfbio.org), a sustainable, service oriented, national data infrastructure facilitating data - sharing for biological and environmental research. -

-
- If you want to learn how to integrate data from GFBio's data search in the VAT tool, have a look at our - How-To. - -
- - Don't show this message again - diff --git a/projects/gfbio-app/src/app/dialogs/splash-dialog/splash-dialog.component.scss b/projects/gfbio-app/src/app/dialogs/splash-dialog/splash-dialog.component.scss deleted file mode 100644 index 5a96303c..00000000 --- a/projects/gfbio-app/src/app/dialogs/splash-dialog/splash-dialog.component.scss +++ /dev/null @@ -1,12 +0,0 @@ -mat-checkbox { - height: 2rem; -} - -img { - vertical-align: middle; - height: 41px; -} - -mat-card.info { - background-color: var(--wave-accent-color, grey); -} diff --git a/projects/gfbio-app/src/app/dialogs/splash-dialog/splash-dialog.component.ts b/projects/gfbio-app/src/app/dialogs/splash-dialog/splash-dialog.component.ts deleted file mode 100644 index 33fc8d98..00000000 --- a/projects/gfbio-app/src/app/dialogs/splash-dialog/splash-dialog.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {Component, ChangeDetectionStrategy, Inject} from '@angular/core'; -import {MatCheckboxChange} from '@angular/material/checkbox'; - -import {UserService} from 'wave-core'; - -import {GFBioUserService} from '../../users/user.service'; - -@Component({ - selector: 'wave-gfbio-splash-dialog', - templateUrl: './splash-dialog.component.html', - styleUrls: ['./splash-dialog.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class SplashDialogComponent { - constructor(@Inject(UserService) private readonly userService: GFBioUserService) {} - - changeTick(event: MatCheckboxChange) { - this.userService.setIntroductoryPopup(!event.checked); - } -} diff --git a/projects/gfbio-app/src/app/help/help.component.html b/projects/gfbio-app/src/app/help/help.component.html deleted file mode 100644 index 1da32a9b..00000000 --- a/projects/gfbio-app/src/app/help/help.component.html +++ /dev/null @@ -1,33 +0,0 @@ -Help - - - - - - - - - Account / Login -

- You can obtain a Vat account by registering at the GFBio portal at - gfbio.org. -

-

Using your GFBio Portal account also allows you to access your stored search results.

-

To log in click the button in the top-right, and select the type of account

-
- - - - - - - - - GFBio Search Results -

- When logged in as a GFBio user, the Add Data function offers a GFBio baskets option. There, you have access to all - previous searches you performed on gfbio.org while being logged in. You have the option to go the data sets landing page or add - a new layer containing the data. -

-
-
diff --git a/projects/gfbio-app/src/app/help/help.component.scss b/projects/gfbio-app/src/app/help/help.component.scss deleted file mode 100644 index e9d76ff5..00000000 --- a/projects/gfbio-app/src/app/help/help.component.scss +++ /dev/null @@ -1,14 +0,0 @@ -:host ::ng-deep mat-expansion-panel { - p { - text-align: justify; - } - - .vat { - font-variant: small-caps; - } - - img.extern { - height: 40px; - padding-right: 5px; - } -} diff --git a/projects/gfbio-app/src/app/help/help.component.ts b/projects/gfbio-app/src/app/help/help.component.ts deleted file mode 100644 index 03dfd5da..00000000 --- a/projects/gfbio-app/src/app/help/help.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-gfbio-help', - templateUrl: './help.component.html', - styleUrls: ['./help.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/projects/gfbio-app/src/app/login/login.component.html b/projects/gfbio-app/src/app/login/login.component.html deleted file mode 100644 index b5116eaa..00000000 --- a/projects/gfbio-app/src/app/login/login.component.html +++ /dev/null @@ -1,30 +0,0 @@ - - - Login - - - - - - - User Info -
-
-

Username

-

Real Name

-

E-Mail

-
-
-

{{ (user | async).name }}

-

{{ (user | async).realName }}

-

{{ (user | async).email }}

-
-
-
- -
-
-
diff --git a/projects/gfbio-app/src/app/login/login.component.scss b/projects/gfbio-app/src/app/login/login.component.scss deleted file mode 100644 index e063a30f..00000000 --- a/projects/gfbio-app/src/app/login/login.component.scss +++ /dev/null @@ -1,29 +0,0 @@ -:host { - display: block; - padding: 1rem; -} - -mat-spinner { - width: 25%; - height: auto; - margin: 1rem auto; -} - -button { - margin-top: 1rem; - width: 100%; - - &.sso-button { - height: 4rem; - - img { - max-height: 50%; - margin-right: 0.5rem; - } - } -} - -.label { - color: var(--wave-foreground-secondary-text-color, grey); - margin-right: 1rem; -} diff --git a/projects/gfbio-app/src/app/login/login.component.ts b/projects/gfbio-app/src/app/login/login.component.ts deleted file mode 100644 index 005f3d95..00000000 --- a/projects/gfbio-app/src/app/login/login.component.ts +++ /dev/null @@ -1,72 +0,0 @@ -import {BehaviorSubject, Observable, Subscription} from 'rxjs'; - -import {Component, OnInit, ChangeDetectionStrategy, AfterViewInit, Inject, ChangeDetectorRef, OnDestroy} from '@angular/core'; -import {Location} from '@angular/common'; - -import {Config, NotificationService, User, UserService} from 'wave-core'; - -import {GFBioUserService} from '../users/user.service'; -import {AppConfig} from '../app-config.service'; - -enum FormStatus { - LoggedOut, - LoggedIn, - Loading, -} - -@Component({ - selector: 'wave-gfbio-login', - templateUrl: './login.component.html', - styleUrls: ['./login.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LoginComponent implements OnInit, AfterViewInit, OnDestroy { - readonly FormStatus = FormStatus; - - formStatus$ = new BehaviorSubject(FormStatus.Loading); - - user: Observable; - - private formStatusSubscription: Subscription; - - constructor( - @Inject(Config) private readonly config: AppConfig, - @Inject(UserService) private readonly userService: GFBioUserService, - private readonly changeDetectorRef: ChangeDetectorRef, - private readonly location: Location, - private readonly notificationService: NotificationService, - ) {} - - ngOnInit() { - this.userService.isSessionValid(this.userService.getSession()).subscribe((valid) => { - const isNoGuest = !this.userService.isGuestUser(); - this.formStatus$.next(valid && isNoGuest ? FormStatus.LoggedIn : FormStatus.LoggedOut); - }); - - this.user = this.userService.getUserStream(); - - this.formStatusSubscription = this.formStatus$.subscribe(() => setTimeout(() => this.changeDetectorRef.markForCheck())); - } - - ngAfterViewInit() {} - - ngOnDestroy() { - if (this.formStatusSubscription) { - this.formStatusSubscription.unsubscribe(); - } - } - - login() { - this.formStatus$.next(FormStatus.Loading); - - this.userService.redirectToOidcProvider(); - } - - logout() { - this.formStatus$.next(FormStatus.Loading); - this.userService.guestLogin().subscribe( - () => this.formStatus$.next(FormStatus.LoggedOut), - (error) => this.notificationService.error(`The backend is currently unavailable (${error})`), - ); - } -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd-repository.component.html b/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd-repository.component.html deleted file mode 100644 index f90e412e..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd-repository.component.html +++ /dev/null @@ -1,23 +0,0 @@ -ABCD Archives - - - -
- - open_in_new -
- - - - open_in_new - -

- -

-
-
- -
-
diff --git a/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd-repository.component.scss b/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd-repository.component.scss deleted file mode 100644 index 44b647c6..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd-repository.component.scss +++ /dev/null @@ -1,36 +0,0 @@ -.datagroup { - color: var(--wave-primary-color, black) !important; -} - -.datagroup a { - color: var(--wave-primary-color, black) !important; -} - -.searchInput { - width: 100%; -} - -mat-list-item { - cursor: pointer; -} - -.highlight, -mat-list-item ::ng-deep .highlight { - color: var(--wave-accent-color, grey); - text-decoration: underline; -} - -.secondary_action { - float: right; -} - -img { - padding: 5px 5px 5px 0; -} - -.link { - max-width: 300px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd-repository.component.ts b/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd-repository.component.ts deleted file mode 100644 index 9cbe2ede..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd-repository.component.ts +++ /dev/null @@ -1,135 +0,0 @@ -import {first, map} from 'rxjs/operators'; -import {Observable, BehaviorSubject} from 'rxjs'; - -import {Component, ChangeDetectionStrategy, Inject} from '@angular/core'; - -import { - UserService, - RandomColorService, - ProjectService, - DataTypes, - DataType, - Unit, - ResultTypes, - Projections, - PointSymbology, - VectorLayer, - Operator, -} from 'wave-core'; - -import {AbcdArchive} from './abcd.model'; -import {ABCDSourceType, ABCDSourceTypeConfig} from '../../types/abcd-source-type.model'; -import {BasicColumns} from '../baskets/csv.model'; -import {GFBioUserService} from '../../../users/user.service'; - -type Grouped = Iterable>; - -interface Group { - group: Array; - name: string; -} - -@Component({ - selector: 'wave-gfbio-abcd-repository', - templateUrl: './abcd-repository.component.html', - styleUrls: ['./abcd-repository.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AbcdRepositoryComponent { - searchString$ = new BehaviorSubject(''); - groups: Observable>; - - constructor( - @Inject(UserService) private readonly userService: GFBioUserService, - private randomColorService: RandomColorService, - private projectService: ProjectService, - ) { - this.groups = this.userService.getAbcdArchivesStream().pipe( - map((archives) => { - const groups: {[groupname: string]: Group} = {}; - - for (const a of archives) { - if (!groups[a.provider]) { - groups[a.provider] = { - group: [], - name: a.provider, - }; - } - groups[a.provider].group.push(a); - } - - const iterableGroups: Array> = []; - const keys = Object.keys(groups).sort(); - for (const key of keys) { - const value = groups[key]; - value.group = value.group.sort((x, y) => (x.dataset < y.dataset ? 0 : 1)); - iterableGroups.push(value); - } - - return iterableGroups; - }), - ); - } - - add(archive: AbcdArchive) { - const basicColumns: BasicColumns = { - numeric: [], - textual: [], - }; - - const attributes: Array = []; - const dataTypes = new Map(); - const units = new Map(); - - this.userService - .getSourceSchemaAbcd() - .pipe(first()) - .subscribe((sourceSchema) => { - for (const attribute of sourceSchema) { - if (attribute.numeric) { - basicColumns.numeric.push(attribute.name); - attributes.push(attribute.name); - dataTypes.set(attribute.name, DataTypes.Float64); // TODO: get more accurate type - units.set(attribute.name, Unit.defaultUnit); - } else { - basicColumns.textual.push(attribute.name); - attributes.push(attribute.name); - dataTypes.set(attribute.name, DataTypes.Alphanumeric); // TODO: get more accurate type - units.set(attribute.name, Unit.defaultUnit); - } - } - - const sourceTypeConfig: ABCDSourceTypeConfig = { - provider: archive.provider, - id: archive.file, - columns: basicColumns, - }; - - const operator = new Operator({ - operatorType: new ABCDSourceType(sourceTypeConfig), - resultType: ResultTypes.POINTS, - projection: Projections.WGS_84, - attributes, - dataTypes, - units, - }); - - const clustered = true; - const layer = new VectorLayer({ - name: archive.dataset, - operator, - symbology: PointSymbology.createClusterSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }), - // data: this.mappingQueryService.getWFSDataStreamAsGeoJsonFeatureCollection({ - // operator, - // clustered, - // }), - // provenance: this.mappingQueryService.getProvenanceStream(operator), - clustered, - }); - // this.layerService.addLayer(layer); - this.projectService.addLayer(layer); - }); - } -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd.model.ts b/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd.model.ts deleted file mode 100644 index dfa1f7c7..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/abcd-repository/abcd.model.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface AbcdArchive { - dataset: string; - file: string; - link: string; - provider: string; -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/csv.model.ts b/projects/gfbio-app/src/app/operators/dialogs/baskets/csv.model.ts deleted file mode 100644 index 3a8e3839..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/csv.model.ts +++ /dev/null @@ -1,46 +0,0 @@ -export interface BasicColumns { - numeric: Array; - textual: Array; -} - -export interface CsvColumns extends BasicColumns { - x?: string; - y?: string; - time1?: string; - time2?: string; -} - -export type CsvTimeType = 'custom' | 'seconds' | 'dmyhm' | 'iso'; - -export interface CsvTimeFormat { - format: CsvTimeType; -} - -export type CsvErrorCase = 'skip' | 'abort' | 'keep'; - -export interface CsvParameters { - separator?: string; - on_error?: CsvErrorCase; - geometry: string; - time: 'none' | 'start' | 'start+end' | 'start+duration'; - time1_format?: CsvTimeFormat; - time2_format?: CsvTimeFormat; - duration?: number; - columns: CsvColumns; -} - -export interface Csv { - name: string; - params: CsvParameters; - geometry_type?: 'points' | 'lines' | 'polygons'; -} - -export interface CsvColumn { - name: string; - numeric: boolean; - unit: string; -} - -export interface CsvFile extends Csv { - filename: string; -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-basket-result.component.ts b/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-basket-result.component.ts deleted file mode 100644 index 2d97a4c5..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-basket-result.component.ts +++ /dev/null @@ -1,62 +0,0 @@ -import {Input, Directive, Inject} from '@angular/core'; - -import { - Operator, - ResultTypes, - VectorLayer, - PointSymbology, - VectorSymbology, - MappingQueryService, - LayerService, - RandomColorService, - UserService, - ProjectService, - UnexpectedResultType, -} from 'wave-core'; - -import {GFBioMappingQueryService} from '../../../queries/mapping-query.service'; -import {IBasketResult} from './gfbio-basket.model'; -import {GFBioUserService} from '../../../users/user.service'; - -@Directive() -// eslint-disable-next-line @angular-eslint/directive-class-suffix -export abstract class BasketResultComponent { - @Input() result: T; - - protected constructor( - @Inject(MappingQueryService) protected readonly mappingQueryService: GFBioMappingQueryService, - protected readonly layerService: LayerService, - protected readonly randomColorService: RandomColorService, - @Inject(UserService) protected readonly userService: GFBioUserService, - protected readonly projectService: ProjectService, - ) {} - - protected createAndAddLayer(operator: Operator, name: string) { - let clustered = false; - let symbology; - - switch (operator.resultType) { - case ResultTypes.POINTS: - symbology = PointSymbology.createClusterSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - clustered = true; - break; - case ResultTypes.POLYGONS: - symbology = VectorSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - break; - default: - throw new UnexpectedResultType(); - } - - const layer = new VectorLayer({ - name, - operator, - symbology, - clustered, - }); - this.projectService.addLayer(layer); - } -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-basket.model.ts b/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-basket.model.ts deleted file mode 100644 index 375af2e7..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-basket.model.ts +++ /dev/null @@ -1,71 +0,0 @@ -import {Moment} from 'moment'; - -import {VectorLayer, AbstractVectorSymbology} from 'wave-core'; - -import {CsvColumn} from './csv.model'; - -export type BasketResult = IBasketAbcdResult | IBasketPangaeaResult; - -export type BasketType = BasketTypeAbcd | BasketTypePangaea | BasketTypeAbcdGrouped; -export type BasketTypeAbcd = 'abcd'; -export type BasketTypeAbcdGrouped = 'abcd_grouped'; -export type BasketTypePangaea = 'pangaea'; - -export interface IBasketResult { - authors: Array; - available: boolean; - dataCenter: string; - dataLink: string; - metadataLink: string; - title: string; - type: BasketType; - resultType: string; -} - -export interface IBasketAbcdResult extends IBasketResult { - unitId?: string; -} - -export interface IBasketGroupedAbcdUnits { - unitId: string; - prefix: string; - type: string; - metadataLink: string; -} - -export interface IBasketGroupedAbcdResult extends IBasketResult { - units: Array; -} - -export interface IBasketPangaeaResult extends IBasketResult { - doi: string; - format: string; - isGeoReferenced?: boolean; - isTabSeparated?: boolean; - parameters: Array; - geometrySpecification: string; - column_x?: string; - column_y?: string; -} - -export interface Basket { - query: string; - results: Array; - timestamp: Moment; -} - -export interface BasketsOverviewBasket { - basketId: number; - query: string; - timestamp: Moment; -} - -export interface BasketsOverview { - baskets: Array; - totalNumberOfBaskets: number; -} - -export interface BasketAvailability { - availableLayers: Array>; - nonAvailableNames: Array; -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-basket.pipe.ts b/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-basket.pipe.ts deleted file mode 100644 index b95f9fbc..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-basket.pipe.ts +++ /dev/null @@ -1,54 +0,0 @@ -import {Pipe, PipeTransform} from '@angular/core'; -import {IBasketResult, IBasketAbcdResult, IBasketGroupedAbcdResult} from './gfbio-basket.model'; - -@Pipe({name: 'waveBasketResultGroupByDatasetPipe'}) -export class BasketResultGroupByDatasetPipe implements PipeTransform { - static regex = /(.*),\s*a\s*(.*)?record\s*of\s*the\s*"(.*)"\s*dataset\s*\[ID:\s*(.*)\]\s*/; - - transform(results: Array): Array { - const array: Array = []; - results.forEach((result) => { - const entry = array.find((b) => b.dataLink === result.dataLink); - - if (result.type === 'abcd') { - const abcd = result as IBasketAbcdResult; - - const unit_type_title_id = BasketResultGroupByDatasetPipe.regex.exec(abcd.title); - const title = unit_type_title_id && unit_type_title_id[3] ? unit_type_title_id[3] : abcd.title; - const unit = - unit_type_title_id && unit_type_title_id[4] - ? { - unitId: unit_type_title_id[4], - prefix: unit_type_title_id[1], - type: unit_type_title_id[2], - metadataLink: abcd.metadataLink, - } - : undefined; - - if (!entry) { - const metadataLink = abcd.metadataLink; - const grouped: IBasketGroupedAbcdResult = { - title, - dataLink: abcd.dataLink, - authors: abcd.authors, - available: abcd.available, - dataCenter: abcd.dataCenter, - metadataLink, - units: unit ? [unit] : [], - type: 'abcd_grouped', - resultType: 'points', - }; - array.push(grouped); - } else { - if (unit) { - const grouped = entry as IBasketGroupedAbcdResult; - grouped.units.push(unit); - } - } - } else if (!entry) { - array.push(result); - } - }); - return array; - } -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-baskets.component.html b/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-baskets.component.html deleted file mode 100644 index 8bf9d5ab..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-baskets.component.html +++ /dev/null @@ -1,55 +0,0 @@ -GFBio Search Baskets - - - - - - Basket History - Select other search results - - -
- -
- - - - -

{{ basketOverview.query }}

-

no search term

-

{{ basketOverview.timestamp | date }}

-
-
- - -
-
- -
- -
- - - - - - - diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-baskets.component.scss b/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-baskets.component.scss deleted file mode 100644 index 62bdaeb0..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-baskets.component.scss +++ /dev/null @@ -1,30 +0,0 @@ -div.loading { - padding: 32px calc(50% - 100px / 2); -} - -mat-progress-spinner { - width: 100px; - height: 100px; -} - -.clickable { - cursor: pointer; -} - -mat-list-item.clickable:hover { - background-color: var(--wave-background-hover-color, grey); -} - -.small { - font-size: small; - color: var(--wave-foreground-secondary-text-color, grey); -} - -.no-search-term { - font-style: italic; -} - -.error-button { - position: absolute; - margin: 2rem calc(50% - (24px / 2)); -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-baskets.component.ts b/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-baskets.component.ts deleted file mode 100644 index a1add838..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/gfbio-baskets.component.ts +++ /dev/null @@ -1,111 +0,0 @@ -import {of as observableOf, combineLatest as observableCombineLatest, ReplaySubject, BehaviorSubject, Subscription} from 'rxjs'; -import {tap, mergeMap, catchError} from 'rxjs/operators'; - -import {ChangeDetectionStrategy, Component, Inject, OnDestroy} from '@angular/core'; - -import * as moment from 'moment'; - -import {MappingQueryService, NotificationService} from 'wave-core'; - -import {Basket, BasketsOverview, BasketTypeAbcdGrouped} from './gfbio-basket.model'; -import {GFBioMappingQueryService} from '../../../queries/mapping-query.service'; - -@Component({ - selector: 'wave-gfbio-baskets', - templateUrl: './gfbio-baskets.component.html', - styleUrls: ['./gfbio-baskets.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class GfbioBasketsComponent implements OnDestroy { - // for template - BasketTypeAbcdGrouped: BasketTypeAbcdGrouped = 'abcd_grouped'; - - page$ = new BehaviorSubject(0); - limit$ = new BehaviorSubject(5); - - basketsOverview$ = new ReplaySubject(1); - selectedBasketId$ = new ReplaySubject(1); - selectedBasket$ = new ReplaySubject(1); - - isOverviewLoading$ = new BehaviorSubject(true); - isDetailsLoading$ = new BehaviorSubject(true); - isError$ = new BehaviorSubject(false); - reload$: BehaviorSubject = new BehaviorSubject(undefined); - - historyExpanded$ = new BehaviorSubject(false); - - private subscriptions: Array = []; - - constructor( - @Inject(MappingQueryService) private mappingQueryService: GFBioMappingQueryService, - private notificationService: NotificationService, - ) { - let initialBasketLoaded = false; - - this.subscriptions.push( - observableCombineLatest(this.page$, this.limit$, this.reload$) - .pipe( - tap(() => this.isOverviewLoading$.next(true)), - mergeMap(([page, limit]) => - this.mappingQueryService.getGFBioBaskets({offset: page * limit, limit}).pipe( - tap(() => this.isError$.next(false)), - catchError((error) => { - this.isError$.next(true); - this.notificationService.error(error); - return observableOf({ - baskets: [], - totalNumberOfBaskets: NaN, - } as BasketsOverview); - }), - ), - ), - tap(() => this.isOverviewLoading$.next(false)), - tap((basketsOverviews) => { - if (!initialBasketLoaded && basketsOverviews.baskets.length > 0) { - this.loadBasket(basketsOverviews.baskets[0].basketId); - initialBasketLoaded = true; - } - }), - ) - .subscribe((basketsOverview) => this.basketsOverview$.next(basketsOverview)), - ); - - this.subscriptions.push( - observableCombineLatest(this.selectedBasketId$, this.reload$) - .pipe( - tap(() => this.isDetailsLoading$.next(true)), - mergeMap(([id]) => - this.mappingQueryService.getGFBioBasket(id).pipe( - tap(() => this.isError$.next(false)), - catchError((error) => { - this.isError$.next(true); - this.notificationService.error(error); - return observableOf({ - query: '', - results: [], - timestamp: moment.invalid(), - } as Basket); - }), - ), - ), - tap(() => this.isDetailsLoading$.next(false)), - ) - .subscribe((basket) => this.selectedBasket$.next(basket)), - ); - } - - ngOnDestroy() { - this.subscriptions.forEach((subscription) => { - subscription.unsubscribe(); - }); - } - - loadBasket(id: number) { - this.selectedBasketId$.next(id); - this.historyExpanded$.next(false); - } - - reload() { - this.reload$.next(undefined); - } -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component.html b/projects/gfbio-app/src/app/operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component.html deleted file mode 100644 index bc3fe72c..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component.html +++ /dev/null @@ -1,64 +0,0 @@ - - - {{ result.title | waveTrimPipe }} - - - - - - - - - - - - - - - - -
Authors - {{ author | waveTrimPipe }} -
Data center{{ result.dataCenter | waveTrimPipe }}
MetadataDataset landing page
- - -

Units from multiple search results based on this dataset:

- - - Unit - {{ unit.prefix }} - - - Type - {{ unit.type }} - - - Unit Id - - {{ unit.unitId }} - - - - - -
-
- - -
- - -
- - - This dataset is currently not available in the VAT system -
    -
  • no georeference detected
  • -
-
-
-
- - diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component.scss b/projects/gfbio-app/src/app/operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component.scss deleted file mode 100644 index c8c128a8..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component.scss +++ /dev/null @@ -1,33 +0,0 @@ -mat-card-header ::ng-deep .mat-card-header-text { - margin: 0 !important; -} - -mat-card-title { - font-size: large !important; - color: var(--wave-primary-color, black); -} - -table.main { - text-align: left; - padding: 0; - border-spacing: 0; - margin-bottom: 1rem; -} - -.main td:first-child { - color: var(--wave-foreground-secondary-text-color, black); - margin-right: 1rem; -} - -.main td:first-child:after { - content: ':'; -} - -.no-bottom-margin { - margin-bottom: 0; -} - -mat-card-actions { - margin-left: 0 !important; - margin-right: 0 !important; -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component.ts b/projects/gfbio-app/src/app/operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component.ts deleted file mode 100644 index 03b86f28..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/grouped-abcd-basket-result/grouped-abcd-basket-result.component.ts +++ /dev/null @@ -1,135 +0,0 @@ -import {Observable, Subscription, of as observableOf} from 'rxjs'; - -import {ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit} from '@angular/core'; -import {DataSource} from '@angular/cdk/collections'; - -import { - RandomColorService, - UserService, - Projections, - MappingQueryService, - LayerService, - ProjectService, - DataType, - DataTypes, - Unit, - ResultTypes, - Operator, -} from 'wave-core'; - -import {BasicColumns, CsvColumn} from '../csv.model'; -import {IBasketGroupedAbcdResult, IBasketGroupedAbcdUnits} from '../gfbio-basket.model'; -import {BasketResultComponent} from '../gfbio-basket-result.component'; -import {ABCDSourceType, ABCDSourceTypeConfig} from '../../../types/abcd-source-type.model'; -import {GFBioMappingQueryService} from '../../../../queries/mapping-query.service'; -import {GFBioUserService} from '../../../../users/user.service'; - -class UnitDataSource extends DataSource { - private units: Array; - - constructor(units: Array) { - super(); - this.units = units; - } - - connect(): Observable> { - return observableOf(this.units); - } - - disconnect() {} -} - -@Component({ - selector: 'wave-gfbio-grouped-abcd-basket-result', - templateUrl: './grouped-abcd-basket-result.component.html', - styleUrls: ['./grouped-abcd-basket-result.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class GroupedAbcdBasketResultComponent extends BasketResultComponent implements OnInit, OnDestroy { - hasUnits = false; - sourceSchema: Array = []; - - unitDataSource: UnitDataSource; - displayedUnitColumns = ['prefix', 'type', 'unitId']; - - private abcdSchemaSubscription: Subscription; - - static createOperatorFromGroupedABCDData( - result: IBasketGroupedAbcdResult, - sourceSchema: Array, - filterUnits: boolean, - ): Operator { - const basicColumns: BasicColumns = { - numeric: [], - textual: [], - }; - - const attributes: Array = []; - const dataTypes = new Map(); - const units = new Map(); - - for (const attribute of sourceSchema) { - if (attribute.numeric) { - basicColumns.numeric.push(attribute.name); - attributes.push(attribute.name); - dataTypes.set(attribute.name, DataTypes.Float64); // TODO: get more accurate type - units.set(attribute.name, Unit.defaultUnit); - } else { - basicColumns.textual.push(attribute.name); - attributes.push(attribute.name); - dataTypes.set(attribute.name, DataTypes.Alphanumeric); // TODO: get more accurate type - units.set(attribute.name, Unit.defaultUnit); - } - } - - const sourceTypeConfig: ABCDSourceTypeConfig = { - provider: result.dataCenter, - id: result.dataLink, - columns: basicColumns, - }; - - if (filterUnits) { - sourceTypeConfig.units = result.units.map((u) => u.unitId); - } - - return new Operator({ - operatorType: new ABCDSourceType(sourceTypeConfig), - resultType: ResultTypes.POINTS, - projection: Projections.WGS_84, - attributes, - dataTypes, - units, - }); - } - - constructor( - @Inject(MappingQueryService) protected readonly mappingQueryService: GFBioMappingQueryService, - protected readonly layerService: LayerService, - protected readonly randomColorService: RandomColorService, - @Inject(UserService) protected readonly userService: GFBioUserService, - protected readonly projectService: ProjectService, - ) { - super(mappingQueryService, layerService, randomColorService, userService, projectService); - } - - ngOnInit() { - this.hasUnits = this.result.units.length > 0; - this.abcdSchemaSubscription = this.userService.getSourceSchemaAbcd().subscribe((schema) => { - // TODO: subscribe when something might change... - this.sourceSchema = schema; - }); - - this.unitDataSource = new UnitDataSource(this.result.units); - } - - ngOnDestroy() { - this.abcdSchemaSubscription.unsubscribe(); - } - - add(filterUnits: boolean) { - this.createAndAddLayer( - GroupedAbcdBasketResultComponent.createOperatorFromGroupedABCDData(this.result, this.sourceSchema, filterUnits), - this.result.title, - ); - } -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component.html b/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component.html deleted file mode 100644 index 434add23..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component.html +++ /dev/null @@ -1,40 +0,0 @@ - - - {{ result.title | waveTrimPipe }} - - - - - - - - - - - - - - - - -
Authors - {{ author | waveTrimPipe }} -
Data center{{ result.dataCenter | waveTrimPipe }}
MetadataDataset landing page
-
- - -
- -
- - - This dataset is currently not available in the VAT system -
    -
  • the data is not tab-separated
  • -
  • no georeference detected
  • -
-
-
-
- - diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component.scss b/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component.scss deleted file mode 100644 index c8c128a8..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component.scss +++ /dev/null @@ -1,33 +0,0 @@ -mat-card-header ::ng-deep .mat-card-header-text { - margin: 0 !important; -} - -mat-card-title { - font-size: large !important; - color: var(--wave-primary-color, black); -} - -table.main { - text-align: left; - padding: 0; - border-spacing: 0; - margin-bottom: 1rem; -} - -.main td:first-child { - color: var(--wave-foreground-secondary-text-color, black); - margin-right: 1rem; -} - -.main td:first-child:after { - content: ':'; -} - -.no-bottom-margin { - margin-bottom: 0; -} - -mat-card-actions { - margin-left: 0 !important; - margin-right: 0 !important; -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component.ts b/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component.ts deleted file mode 100644 index 5427fb92..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea-basket-result/pangaea-basket-result.component.ts +++ /dev/null @@ -1,98 +0,0 @@ -import {ChangeDetectionStrategy, Component, Inject} from '@angular/core'; - -import { - RandomColorService, - UserService, - Projections, - MappingQueryService, - LayerService, - ProjectService, - DataType, - DataTypes, - Unit, - ResultTypes, - Operator, -} from 'wave-core'; - -import {CsvColumns, CsvParameters} from '../csv.model'; -import {IBasketPangaeaResult} from '../gfbio-basket.model'; -import {BasketResultComponent} from '../gfbio-basket-result.component'; -import {PangaeaSourceType} from '../../../types/pangaea-source-type.model'; -import {GFBioMappingQueryService} from '../../../../queries/mapping-query.service'; -import {GFBioUserService} from '../../../../users/user.service'; - -@Component({ - selector: 'wave-gfbio-pangaea-basket-result', - templateUrl: './pangaea-basket-result.component.html', - styleUrls: ['./pangaea-basket-result.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class PangaeaBasketResultComponent extends BasketResultComponent { - static createOperatorFromPangaeaData(result: IBasketPangaeaResult): Operator { - const csvColumns: CsvColumns = { - numeric: [], - textual: [], - x: '', - y: '', - }; - - const attributes: Array = []; - const dataTypes = new Map(); - const units = new Map(); - - for (const attribute of result.parameters) { - if (attribute.numeric) { - csvColumns.numeric.push(attribute.name); - attributes.push(attribute.name); - dataTypes.set(attribute.name, DataTypes.Float64); // TODO: get more accurate type - units.set(attribute.name, Unit.defaultUnit); - } else { - csvColumns.textual.push(attribute.name); - attributes.push(attribute.name); - dataTypes.set(attribute.name, DataTypes.Alphanumeric); // TODO: get more accurate type - units.set(attribute.name, Unit.defaultUnit); - } - } - - csvColumns.x = result.column_x; - csvColumns.y = result.column_y; - - const csvParameters: CsvParameters = { - geometry: result.geometrySpecification, - separator: '\t', - time: 'none', - columns: csvColumns, - on_error: 'keep', // TODO: let the user decide on this - }; - - return new Operator({ - operatorType: new PangaeaSourceType({ - doi: result.doi, - csvParameters, - }), - resultType: ResultTypes.fromCode(result.resultType), - projection: Projections.WGS_84, - attributes, - dataTypes, - units, - }); - } - - constructor( - @Inject(MappingQueryService) protected readonly mappingQueryService: GFBioMappingQueryService, - protected readonly layerService: LayerService, - protected readonly randomColorService: RandomColorService, - @Inject(UserService) protected readonly userService: GFBioUserService, - protected readonly projectService: ProjectService, - ) { - super(mappingQueryService, layerService, randomColorService, userService, projectService); - } - - createResultOperator(): Operator { - return PangaeaBasketResultComponent.createOperatorFromPangaeaData(this.result); - } - - addDataset() { - this.createAndAddLayer(this.createResultOperator(), this.result.title); - } -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea.model.ts b/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea.model.ts deleted file mode 100644 index 07c468d7..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/baskets/pangaea.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {Csv} from './csv.model'; - -export interface PangaeaDataset extends Csv { - datalink: string; -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/terminology-lookup/terminology-lookup.component.html b/projects/gfbio-app/src/app/operators/dialogs/terminology-lookup/terminology-lookup.component.html deleted file mode 100644 index 19358c89..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/terminology-lookup/terminology-lookup.component.html +++ /dev/null @@ -1,72 +0,0 @@ -GFBio Terminology Lookup -
-
- - - - - {{ attribute }} - - - - - - [{{ terminology.acronym }}] {{ terminology.name }} - - - - - - - - The terminology_key must be non-empty. - - - - - - - The resolved attribute name must be non-empty. - - - - - - {{ TerminologyLookupOnNotResolvable.KEEP }} - {{ TerminologyLookupOnNotResolvable.EMPTY }} - - - - - - {{ TerminologyLookupMatchType.EXACT }} - {{ TerminologyLookupMatchType.INCLUDED }} - {{ TerminologyLookupMatchType.REGEX }} - - - - Use first hit - - - - The name must be non-empty. - - -
-
- -
-
diff --git a/projects/gfbio-app/src/app/operators/dialogs/terminology-lookup/terminology-lookup.component.scss b/projects/gfbio-app/src/app/operators/dialogs/terminology-lookup/terminology-lookup.component.scss deleted file mode 100644 index f907881f..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/terminology-lookup/terminology-lookup.component.scss +++ /dev/null @@ -1,24 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -.actions { - text-align: right; - padding: 1rem; -} - -mat-form-field { - width: 100% !important; - margin: 0 0 1rem 0; -} - -.error { - color: var(--wave-warn-color, red); -} diff --git a/projects/gfbio-app/src/app/operators/dialogs/terminology-lookup/terminology-lookup.component.ts b/projects/gfbio-app/src/app/operators/dialogs/terminology-lookup/terminology-lookup.component.ts deleted file mode 100644 index fa0fd16d..00000000 --- a/projects/gfbio-app/src/app/operators/dialogs/terminology-lookup/terminology-lookup.component.ts +++ /dev/null @@ -1,316 +0,0 @@ -import {Observable} from 'rxjs'; -import {map, tap} from 'rxjs/operators'; - -import {AfterViewInit, ChangeDetectionStrategy, Component} from '@angular/core'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; - -import { - VectorLayer, - AbstractVectorSymbology, - Operator, - ProjectService, - WaveValidators, - RandomColorService, - DataTypes, - ResultTypes, -} from 'wave-core'; -import {TerminologyLookupType, TerminologyLookupOnNotResolvable, TerminologyLookupMatchType} from '../../types/terminology-lookup-type'; - -// TODO: replace with actual lookup -const TERMINOLOGIES: Array<{name: string; acronym: string; description: string; uri: string}> = [ - { - name: 'Biological Collections Ontology', - acronym: 'BCO', - description: - "The biological collection ontology includes consideration of the distinctions between individuals, organisms, voucher specimens, lots, and samples the relations between these entities, and processes governing the creation and use of 'samples'. Within scope as well are properties including collector, location, time, storage environment, containers, institution, and collection identifiers. ", - uri: 'http://purl.obolibrary.org/obo/bco.owl', - }, - { - name: 'Flora Phenotype Ontology', - acronym: 'FLOPO', - description: - 'The Flora Phenotype Ontology is an ontology of phenotypes reported in Floras. The original version was developed at the pro-iBiosphere Hackathon in Leiden. This is the pre-classified version of the ontology; the original OWL file is at https://github.com/flora-phenotype-ontology/flopoontology/blob/master/ontology/flopo.owl The Flora Phenotype Ontology is generated from the Flora Malesiana, Flora Gabon, Flora of Central Africa, and a collection of Kews African Floras. Every class in the ontology has at least one taxon annotation. The (draft) taxon annotation are available at http://jagannath.pdn.cam.ac.uk/plant/flora/clean-rerun/', - uri: 'http://purl.obolibrary.org/obo/flopo.owl', - }, - { - name: 'Phenotypic Quality Ontology', - acronym: 'PATO', - description: - 'Phenotypic qualities (properties). This ontology can be used in conjunction with other ontologies such as GO or anatomical ontologies to refer to phenotypes. Examples of qualities are red, ectopic, high temperature, fused, small, edematous and arrested.', - uri: 'http://purl.obolibrary.org/obo/pato.owl', - }, - { - name: 'Chemical Entities of Biological Interest Ontology', - acronym: 'CHEBI', - description: 'A structured classification of chemical compounds of biological relevance.', - uri: 'http://purl.obolibrary.org/obo/chebi/160/chebi.owl', - }, - { - name: 'RecordBasis', - acronym: 'RECORDBASIS', - description: - "A controlled vocabulary (Terminology) 'BasisOfRecords' or 'RecordBasis' (DwC: “The specific nature of the data record.”). Based on GBIF/ DwC and BiNHum/ABCD.", - uri: 'http://terminologies.gfbio.org/terms/RECORDBASIS', - }, - { - name: 'Bohlmann Ontology', - acronym: 'BOHLMANN', - description: 'An ontology listing the natural substances that occurr in the plant family of Compositae (Asteraceae).', - uri: 'http://terminologies.gfbio.org/terms/BOHLMANN', - }, - { - name: 'Trichoptera Ontology', - acronym: 'TRICHOPTERA', - description: 'Working list: taxon names of the order Trichoptera (caddisflies; Insecta).', - uri: 'http://terminologies.gfbio.org/terms/TRICHOPTERA/', - }, - { - name: 'Environment Ontology', - acronym: 'ENVO', - description: - 'Official PURL: http://purl.obolibrary.org/obo/envo.owl The most up-to-date information about ENVO is available here: http://www.obofoundry.org/ontology/envo.html EnvO is an OBO Foundry and Library ontology for the concise, controlled description of environmental entities such as ecosystems, environmental processes, and environmental qualities. It closely interoperates with a broad collection of other OBO ontologies and is used in a diverse range of projects.', - uri: 'http://purl.obolibrary.org/obo/envo.owl', - }, - { - name: 'Thysanoptera Ontology', - acronym: 'THYSANOPTERA', - description: 'Working list: taxon names of the order Thysanoptera (Insecta).', - uri: 'http://terminologies.gfbio.org/terms/THYSANOPTERA/', - }, - { - name: 'The Extensible Observation Ontology', - acronym: 'OBOE', - description: - 'The Extensible Observation Ontology (OBOE) is a formal ontology for capturing the semantics of scientific observation and measurement. The ontology supports researchers to add detailed semantic annotations to scientific data, thereby clarifying the inherent meaning of scientific observations.', - uri: 'http://ecoinformatics.org/oboe/oboe.1.2/oboe.owl', - }, - { - name: 'Kingdom', - acronym: 'KINGDOM', - description: - "A controlled vocabulary (Terminology) for biological taxa 'Higher Classification - Kingdom (=Regnum)'. Based on GBIF and CoL.", - uri: 'http://terminologies.gfbio.org/terms/KINGDOM', - }, - { - name: 'Plant Trait Ontology', - acronym: 'PTO', - description: - 'A controlled vocabulary to describe phenotypic traits in plants. Each trait is a distinguishable feature, characteristic, quality or phenotypic feature of a developing or mature plant, or a plant part.', - uri: 'http://purl.obolibrary.org/obo/to.owl', - }, - { - name: 'Oribatida Ontology', - acronym: 'ORIBATIDA', - description: 'Working list: taxon names of the order Oribatida (moss- or beetle-mites).', - uri: 'http://terminologies.gfbio.org/terms/ORIBATIDA/', - }, - { - name: 'Quantity, Unit, Dimension and Type', - acronym: 'QUDT', - description: - 'The QUDT collection of ontologies define the base classes properties, and restrictions used for modeling physical quantities, units of measure, and their dimensions in various measurement systems. The goal of the QUDT ontology is to provide a unified model of, measurable quantities, units for measuring different kinds of quantities, the numerical values of quantities in different units of measure and the data structures and data types used to store and manipulate these objects in software. This OWL schema is a foundation for a basic treatment of units.', - uri: 'http://data.qudt.org/qudt/owl/1.0.0/qudt-all.owl', - }, - { - name: 'Semantic Web for Earth and Environment Technology Ontology', - acronym: 'SWEET', - description: - 'The Semantic Web for Earth and Environmental Terminology is a mature foundational ontology that contains over 6000 concepts organized in 200 ontologies represented in OWL. Top level concepts include Representation (math, space, science, time, data), Realm (Ocean, Land Surface, Terrestrial Hydroshere, Atmosphere, etc.), Phenomena (macro-scale ecological and physical), Processes (micro-scale physical, biological, chemical, and mathematical), Human Activities (Decision, Commerce, Jurisdiction, Environmental, Research). Originally developed by NASA Jet Propulsion Labs under Rob Raskin, SWEET is now officially under the governance of the ESIP foundation.', - uri: 'http://sweetontology.net/sweetAll', - }, - { - name: 'ISO 3166 Countries and Subdivisions', - acronym: 'ISOCOUNTRIES', - description: 'ISO 3166 Countries and Subdivisions', - uri: 'http://terminologies.gfbio.org/terms/ISOCOUNTRIES', - }, - { - name: 'The lithologs rock names ontology for igneous rocks', - acronym: 'LIT_I', - description: - 'The lithologs ontology for igneous rocks provides SKOSified information on the classification of igneous rocks extracted from the IUGS recommendations published by Le Maitre (ed.)(2002): Igneous rocks: a classification and glossary of terms', - uri: 'http://terminologies.gfbio.org/terms/LIT_I', - }, - { - name: 'National Center for Biotechnology Information (NCBI) Organismal Classification', - acronym: 'NCBITAXON', - description: - 'The NCBI Taxonomy Database is a curated classification and nomenclature for all of the organisms in the public sequence databases.', - uri: 'http://purl.obolibrary.org/obo/ncbitaxon.owl', - }, - { - name: 'Regionalised and Domain-specific Taxon Lists', - acronym: 'DTNtaxonlists_SNSB', - description: - 'The DWB REST Webservice for Taxon Lists is part of a Diversity Workbench (DWB) services network. It is delivering basic information on taxon names in use, synonyms, classification and German vernacular names of a number of groups of animals, fungi and plants. The current focus is on domain-specific lists (checklists, taxon reference lists, red lists) from Germany under active curation by experts on taxonomy or floristics and faunistics. Each regionalised and domain-specific taxon list has its own history and objectives, is managed completely separately and has its own hierarchical classification. The DiversityTaxonNames (DTN) data resources accessed by the REST API may include additional taxon-related data useful, e. g., for regional nature conservation agencies and environmental projects. This information might be mobilised in a next step. For more information please check the Overview on Published Lists ( http://services.snsb.info/DTNtaxonlists/rest/v0.1/) and the REST-API documentation ( http://services.snsb.info/DTNtaxonlists/rest/v0.1/static/api-doc.html).', - uri: 'http://www.eu-nomen.eu/portal/taxon.php?GUID=', - }, - { - name: 'Catalogue Of Life', - acronym: 'COL', - description: - 'The Catalogue of Life is the most comprehensive and authoritative global index of species currently available. It consists of a single integrated species checklist and taxonomic hierarchy. The Catalogue holds essential information on the names, relationships and distributions of over 1.7 million species. This figure continues to rise as information is compiled from diverse sources around the world. . Accessed via: https://cybertaxonomy.eu/cdmlib/rest-api-name-catalogue.html.', - uri: 'http://api.cybertaxonomy.org/col/name_catalogue/', - }, - { - name: 'Prokaryotic Nomenclature up-to-date', - acronym: 'PNU', - description: - "PNU is a compilation of all names of Bacteria and Archaea which have been validly published according to the Bacteriological Code since 1. Jan. 1980, and nomenclatural changes which have been validly published since. It will be updated with the publication of each new issue of the Int. J. Syst. Evol. Microbiol. (IJSEM). 'Prokaryotic Nomenclature up-to-date' is published by the Leibniz-Institut DSMZ - Deutsche Sammlung von Mikroorganismen und Zellkulturen GmbH.", - uri: 'http://bacdive.dsmz.de/api/pnu/', - }, - { - name: 'Integrated Taxonomic Information System', - acronym: 'ITIS', - description: - 'The White House Subcommittee on Biodiversity and Ecosystem Dynamics has identified systematics as a research priority that is fundamental to ecosystem management and biodiversity conservation. This primary need identified by the Subcommittee requires improvements in the organization of, and access to, standardized nomenclature. ITIS (originally referred to as the Interagency Taxonomic Information System) was designed to fulfill these requirements. In the future, the ITIS will provide taxonomic data and a directory of taxonomic expertise that will support the system. The ITIS is the result of a partnership of federal agencies formed to satisfy their mutual needs for scientifically credible taxonomic information. Since its inception, ITIS has gained valuable new partners and undergone a name change; ITIS now stands for the Integrated Taxonomic Information System. ', - uri: 'http://www.itis.gov/', - }, - { - name: 'The GeoNames geographical database', - acronym: 'GEONAMES', - description: - 'The GeoNames geographical database is available for download free of charge under a creative commons attribution license. It contains over 10 million geographical names and consists of over 9 million unique features whereof 2.8 million populated places and 5.5 million alternate names. All features are categorized into one out of nine feature classes and further subcategorized into one out of 645 feature codes.', - uri: 'http://sws.geonames.org/', - }, - { - name: 'Pan-European Species directories Infrastructure', - acronym: 'PESI', - description: - 'PESI provides standardised and authoritative taxonomic information by integrating and securing Europes taxonomically authoritative species name registers and nomenclators (name databases) and associated exper(tise) networks that underpin the management of biodiversity in Europe.', - uri: 'http://www.eu-nomen.eu/portal/taxon.php?GUID=', - }, - { - name: 'World Register of Marine Species', - acronym: 'WORMS', - description: - 'The aim of a World Register of Marine Species (WoRMS) is to provide an authoritative and comprehensive list of names of marine organisms, including information on synonymy. While highest priority goes to valid names, other names in use are included so that this register can serve as a guide to interpret taxonomic literature.', - uri: 'http://www.marinespecies.org/aphia.php?p=soap', - }, -]; - -/** - * This component allows creating the terminology lookup operator. - */ -@Component({ - selector: 'wave-gfbio-terminology-lookup', - templateUrl: './terminology-lookup.component.html', - styleUrls: ['./terminology-lookup.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class TerminologyLookupOperatorComponent implements AfterViewInit { - // for the template - readonly ResultTypes = ResultTypes; - TerminologyLookupOnNotResolvable = TerminologyLookupOnNotResolvable; - TerminologyLookupMatchType = TerminologyLookupMatchType; - TERMINOLOGIES = TERMINOLOGIES; - - form: FormGroup; - attributes$: Observable>; - - constructor(private projectService: ProjectService, private formBuilder: FormBuilder, private randomColorService: RandomColorService) { - this.form = formBuilder.group({ - name: [undefined, [Validators.required, WaveValidators.notOnlyWhitespace]], - vectorLayer: [undefined, Validators.required], - attribute: [undefined, Validators.required], - terminology: ['ISOCOUNTRIES', Validators.required], - terminology_key: ['label', [Validators.required, WaveValidators.notOnlyWhitespace]], - resolved_attribute_name: [undefined, [Validators.required, WaveValidators.notOnlyWhitespace]], - matchType: [TerminologyLookupMatchType.INCLUDED, []], - on_not_resolvable: [TerminologyLookupOnNotResolvable.EMPTY, Validators.required], - first_hit: [true, []], - }); - - this.attributes$ = this.form.controls['vectorLayer'].valueChanges.pipe( - tap((layer) => { - // side effects!!! - this.form.controls['attribute'].setValue(undefined); - if (layer) { - this.form.controls['attribute'].enable({onlySelf: true}); - } else { - this.form.controls['attribute'].disable({onlySelf: true}); - } - }), - map((layer) => { - if (layer) { - return layer.operator.attributes.toArray().sort(); - } else { - return []; - } - }), - ); - } - - ngAfterViewInit() { - // initially get attributes - setTimeout(() => this.form.controls['vectorLayer'].enable({emitEvent: true})); - } - - add() { - const vectorLayer: VectorLayer = this.form.controls['vectorLayer'].value; - const sourceOperator: Operator = vectorLayer.operator; - - const attributeName: string = this.form.controls['attribute'].value; - const terminologyName: string = this.form.controls['terminology'].value; - const terminologyKeyName: string = this.form.controls['terminology_key'].value; - - const on_not_resolvable: TerminologyLookupOnNotResolvable = this.form.controls['on_not_resolvable'].value; - const match_type: TerminologyLookupMatchType = this.form.controls['matchType'].value; - const first_hit: boolean = this.form.controls['first_hit'].value; - const resolved_attribute_name = this.form.controls['resolved_attribute_name'].value; - - const name: string = this.form.controls['name'].value; - - // TODO: handle new terminology name and add it to the attribute list! - const operatorAttributes = sourceOperator.attributes.toArray(); - operatorAttributes.push(resolved_attribute_name); - const operatorDataTypes = sourceOperator.dataTypes.set('resolved_attribute_name', DataTypes.Alphanumeric); - - const dict = { - operatorType: new TerminologyLookupType({ - attribute_name: attributeName, - terminology: terminologyName, - key: terminologyKeyName, - on_not_resolvable, - resolved_attribute: resolved_attribute_name, - match_type, - first_hit, - }), - resultType: sourceOperator.resultType, - projection: sourceOperator.projection, - attributes: operatorAttributes, - dataTypes: operatorDataTypes, - units: sourceOperator.units, - pointSources: [], - lineSources: [], - polygonSources: [], - }; - - switch (sourceOperator.resultType) { - case ResultTypes.POINTS: - dict.pointSources.push(sourceOperator); - break; - case ResultTypes.LINES: - dict.lineSources.push(sourceOperator); - break; - case ResultTypes.POLYGONS: - dict.polygonSources.push(sourceOperator); - break; - default: - throw Error('Incompatible Input Type'); - } - - const operator = new Operator(dict); - - const symbology = (vectorLayer.symbology.clone() as any) as AbstractVectorSymbology; - symbology.fillRGBA = this.randomColorService.getRandomColorRgba(); - const layer = new VectorLayer({ - name, - operator, - symbology, - clustered: vectorLayer.clustered, - }); - - this.projectService.addLayer(layer); - } -} diff --git a/projects/gfbio-app/src/app/operators/types/abcd-source-type.model.ts b/projects/gfbio-app/src/app/operators/types/abcd-source-type.model.ts deleted file mode 100644 index f3f82e44..00000000 --- a/projects/gfbio-app/src/app/operators/types/abcd-source-type.model.ts +++ /dev/null @@ -1,107 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from 'wave-core'; -import {BasicColumns} from '../dialogs/baskets/csv.model'; - -export interface ABCDSourceTypeConfig { - provider: string; - id: string; - units?: Array; - columns?: BasicColumns; -} - -interface ABCDSourceTypeMappingDict extends OperatorTypeMappingDict { - path: string; - units: Array; - columns: BasicColumns; -} - -export interface ABCDSourceTypeDict extends OperatorTypeDict { - provider: string; - id: string; - units: Array; - columns?: BasicColumns; -} - -/** - * The ABCD source type. - */ -export class ABCDSourceType extends OperatorType { - private static _TYPE = 'abcd_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(ABCDSourceType._TYPE); - private static _NAME = 'ABCD Source'; - - static get TYPE(): string { - return ABCDSourceType._TYPE; - } - - static get ICON_URL(): string { - return ABCDSourceType._ICON_URL; - } - - static get NAME(): string { - return ABCDSourceType._NAME; - } - - private provider: string; - private id: string; - private units: Array; - private columns: BasicColumns; - - constructor(config: ABCDSourceTypeConfig) { - super(); - this.provider = config.provider; - this.id = config.id; - this.units = config.units ? config.units : []; - this.columns = config.columns; - } - - static fromDict(dict: ABCDSourceTypeDict): ABCDSourceType { - return new ABCDSourceType({ - provider: dict.provider, - id: dict.id, - units: dict.units, - columns: dict.columns ? dict.columns : {textual: [], numeric: []}, - }); - } - - getMappingName(): string { - return ABCDSourceType.TYPE; - } - - getIconUrl(): string { - return ABCDSourceType.ICON_URL; - } - - toString(): string { - return ABCDSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['archive', this.provider], - ['id', this.id], - ['units', this.units.join(', ')], - ]; - } - - toMappingDict(): ABCDSourceTypeMappingDict { - return { - path: this.id, - units: this.units, - columns: this.columns, - }; - } - - toDict(): ABCDSourceTypeDict { - return { - operatorType: ABCDSourceType.TYPE, - provider: this.provider, - id: this.id, - units: this.units, - columns: this.columns, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return ABCDSourceType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/gfbio-app/src/app/operators/types/pangaea-source-type.model.ts b/projects/gfbio-app/src/app/operators/types/pangaea-source-type.model.ts deleted file mode 100644 index a4d4a1be..00000000 --- a/projects/gfbio-app/src/app/operators/types/pangaea-source-type.model.ts +++ /dev/null @@ -1,92 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from 'wave-core'; -import {CsvParameters} from '../dialogs/baskets/csv.model'; - -interface PangaeaSourceTypeConfig { - doi: string; - csvParameters: CsvParameters; -} - -interface PangaeaSourceTypeMappingDict extends OperatorTypeMappingDict, CsvParameters { - doi: string; -} - -export interface PangaeaSourceTypeDict extends OperatorTypeDict { - doi: string; - csvParameters: CsvParameters; -} - -/** - * The Pangaea source type. - */ -export class PangaeaSourceType extends OperatorType { - private static _TYPE = 'pangaea_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(PangaeaSourceType._TYPE); - private static _NAME = 'Pangaea Source'; - - static get TYPE(): string { - return PangaeaSourceType._TYPE; - } - - static get ICON_URL(): string { - return PangaeaSourceType._ICON_URL; - } - - static get NAME(): string { - return PangaeaSourceType._NAME; - } - - private doi: string; - private csvParameters: CsvParameters; - - constructor(config: PangaeaSourceTypeConfig) { - super(); - this.doi = config.doi; - this.csvParameters = config.csvParameters; - } - - static fromDict(dict: PangaeaSourceTypeDict): PangaeaSourceType { - return new PangaeaSourceType({ - doi: dict.doi, - csvParameters: dict.csvParameters, - }); - } - - getMappingName(): string { - return PangaeaSourceType.TYPE; - } - - getIconUrl(): string { - return PangaeaSourceType.ICON_URL; - } - - toString(): string { - return PangaeaSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['doi', this.doi], - ['geometry', this.csvParameters.geometry], - ['separator', this.csvParameters.separator ? this.csvParameters.separator : ''], - ['time', this.csvParameters.time ? this.csvParameters.time : ''], - ]; - } - - toMappingDict(): PangaeaSourceTypeMappingDict { - let dict = this.csvParameters as PangaeaSourceTypeMappingDict; - dict.doi = this.doi; - return dict; - } - - toDict(): PangaeaSourceTypeDict { - return { - operatorType: PangaeaSourceType.TYPE, - doi: this.doi, - csvParameters: this.csvParameters, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return PangaeaSourceType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/gfbio-app/src/app/operators/types/terminology-lookup-type.ts b/projects/gfbio-app/src/app/operators/types/terminology-lookup-type.ts deleted file mode 100644 index 308140e9..00000000 --- a/projects/gfbio-app/src/app/operators/types/terminology-lookup-type.ts +++ /dev/null @@ -1,150 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from 'wave-core'; - -export enum TerminologyLookupOnNotResolvable { - EMPTY = 'EMPTY', - KEEP = 'KEEP', -} - -export enum TerminologyLookupMatchType { - EXACT = 'exact', - INCLUDED = 'included', - REGEX = 'regex', -} - -interface TerminologyLookupTypeMappingDict extends OperatorTypeMappingDict { - attribute_name: string; - resolved_attribute: string; - terminology: string; - key?: string; - match_type?: 'exact' | 'included' | 'regex'; - first_hit?: boolean; - on_not_resolvable: 'EMPTY' | 'KEEP'; -} - -export interface TerminologyLookupTypeDict extends OperatorTypeDict { - attribute_name: string; - resolved_attribute: string; - terminology: string; - key: string; - match_type: TerminologyLookupMatchType; - first_hit: boolean; - on_not_resolvable: TerminologyLookupOnNotResolvable; -} - -interface TerminologyLookupTypeConfig { - attribute_name: string; - resolved_attribute: string; - terminology: string; - key?: string; - match_type?: TerminologyLookupMatchType; - first_hit?: boolean; - on_not_resolvable: TerminologyLookupOnNotResolvable; -} - -/** - * The Terminology Resolver type. - */ -export class TerminologyLookupType extends OperatorType { - private static _TYPE = 'terminology_resolver'; - private static _ICON_URL = OperatorType.createIconDataUrl(TerminologyLookupType._TYPE); - private static _NAME = 'Terminology Resolver'; - - static get TYPE(): string { - return TerminologyLookupType._TYPE; - } - - static get ICON_URL(): string { - return TerminologyLookupType._ICON_URL; - } - - static get NAME(): string { - return TerminologyLookupType._NAME; - } - - attribute_name: string; - resolved_attribute_name: string; - terminology: string; - key: string; - match_type: TerminologyLookupMatchType; - first_hit: boolean; - on_not_resolvable: TerminologyLookupOnNotResolvable; - new_column_appendix: string; - define_new_column_appendix: boolean; - - static fromDict(dict: TerminologyLookupTypeDict): TerminologyLookupType { - return new TerminologyLookupType(dict); - } - - constructor(config: TerminologyLookupTypeConfig) { - super(); - this.attribute_name = config.attribute_name; - this.resolved_attribute_name = config.resolved_attribute; - this.terminology = config.terminology; - this.key = config.key; - this.match_type = config.match_type ? config.match_type : TerminologyLookupMatchType.EXACT; - this.first_hit = !!config.first_hit; - this.on_not_resolvable = config.on_not_resolvable ? config.on_not_resolvable : TerminologyLookupOnNotResolvable.EMPTY; - } - - getMappingName(): string { - return TerminologyLookupType.TYPE; - } - - getIconUrl(): string { - return TerminologyLookupType.ICON_URL; - } - - toString(): string { - return TerminologyLookupType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['attribute_name', this.attribute_name.toString()], - ['resolved_attribute_name', this.resolved_attribute_name.toString()], - ['terminology', this.terminology.toString()], - ['key', this.key.toString()], - ['match_type', this.match_type.toString()], - ['first_hit', this.first_hit.toString()], - ['on_not_resolvable', this.on_not_resolvable.toString()], - ]; - } - - toMappingDict(): TerminologyLookupTypeMappingDict { - const dict = { - attribute_name: this.attribute_name, - resolved_attribute: this.resolved_attribute_name, - terminology: this.terminology, - on_not_resolvable: this.on_not_resolvable.toString(), - first_hit: this.first_hit, - }; - - if (this.key) { - dict['key'] = this.key; - } - if (this.match_type) { - dict['match_type'] = this.match_type; // TODO: remove cast? - } - return dict as TerminologyLookupTypeMappingDict; - } - - toDict(): TerminologyLookupTypeDict { - return { - operatorType: TerminologyLookupType.TYPE, - attribute_name: this.attribute_name, - resolved_attribute: this.resolved_attribute_name, - terminology: this.terminology, - on_not_resolvable: this.on_not_resolvable, - first_hit: this.first_hit, - key: this.key, - match_type: this.match_type, - - // define_new_column_appendix: this.define_new_column_appendix, - // new_column_appendix: this.new_column_appendix - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return TerminologyLookupType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/gfbio-app/src/app/queries/mapping-query.service.ts b/projects/gfbio-app/src/app/queries/mapping-query.service.ts deleted file mode 100644 index a9260ddc..00000000 --- a/projects/gfbio-app/src/app/queries/mapping-query.service.ts +++ /dev/null @@ -1,137 +0,0 @@ -import {Inject, Injectable} from '@angular/core'; -import {HttpClient} from '@angular/common/http'; - -import {Observable} from 'rxjs'; -import {map} from 'rxjs/operators'; - -import * as moment from 'moment'; - -import {MappingRequestParameters, MappingQueryService, UserService, Config} from 'wave-core'; - -import { - Basket, - BasketResult, - BasketsOverview, - IBasketAbcdResult, - IBasketGroupedAbcdResult, -} from '../operators/dialogs/baskets/gfbio-basket.model'; -import {GFBioUserService} from '../users/user.service'; -import {AppConfig} from '../app-config.service'; - -@Injectable() -export class GFBioMappingQueryService extends MappingQueryService { - constructor( - @Inject(Config) protected readonly config: AppConfig, - protected readonly http: HttpClient, - @Inject(UserService) protected readonly userService: GFBioUserService, - ) { - super(config, http, userService); - } - - getGFBioBaskets(config: {offset: number; limit: number}): Observable { - const parameters = new MappingRequestParameters({ - service: 'gfbio', - request: 'baskets', - sessionToken: this.userService.getSession().sessionToken, - parameters: { - offset: config.offset, - limit: config.limit, - }, - }); - - const queryUrl = this.config.MAPPING_URL + '?' + parameters.toMessageBody(); - - interface BasketsOverviewRaw { - baskets: Array<{ - basketId: number; - query: string; - timestamp: string; - }>; - totalNumberOfBaskets: number; - } - - return this.http.get(queryUrl).pipe( - map((basketsOverview: BasketsOverviewRaw) => { - return { - baskets: basketsOverview.baskets.map((basket) => { - return { - basketId: basket.basketId, - query: basket.query, - timestamp: moment(basket.timestamp, 'YYYY-MM-DD HH:mm:ss.S'), - }; - }), - totalNumberOfBaskets: basketsOverview.totalNumberOfBaskets, - }; - }), - ); - } - - getGFBioBasket(id: number): Observable { - const parameters = new MappingRequestParameters({ - service: 'gfbio', - request: 'basket', - sessionToken: this.userService.getSession().sessionToken, - parameters: { - id, - }, - }); - - const queryUrl = this.config.MAPPING_URL + '?' + parameters.toMessageBody(); - - return this.http.get(queryUrl).pipe( - map((basket: Basket) => { - const regex = /(.*),\s*a\s*(.*)?record\s*of\s*the\s*"(.*)"\s*dataset\s*\[ID:\s*(.*)]\s*/; - - const basketResults: Array = []; - basket.results.forEach((result) => { - const entry = basketResults.find((b) => b.dataLink === result.dataLink); - - if (result.type === 'abcd') { - const abcd = result as IBasketAbcdResult; - - const unit_type_title_id = regex.exec(abcd.title); - const title = unit_type_title_id && unit_type_title_id[3] ? unit_type_title_id[3] : abcd.title; - const unit = - unit_type_title_id && unit_type_title_id[4] - ? { - unitId: unit_type_title_id[4], - prefix: unit_type_title_id[1], - type: unit_type_title_id[2], - metadataLink: abcd.metadataLink, - } - : undefined; - - if (!entry) { - const metadataLink = abcd.metadataLink; - const grouped: IBasketGroupedAbcdResult = { - title, - dataLink: abcd.dataLink, - authors: abcd.authors, - available: abcd.available, - dataCenter: abcd.dataCenter, - metadataLink, - units: unit ? [unit] : [], - type: 'abcd_grouped', - resultType: 'points', - }; - basketResults.push(grouped); - } else { - if (unit) { - const grouped = entry as IBasketGroupedAbcdResult; - grouped.units.push(unit); - } - } - } else if (!entry) { - basketResults.push(result); - } - }); - - return { - query: basket.query, - results: basketResults, - timestamp: moment(basket.timestamp, 'MM-DD-YYYY HH:mm:ss.SSS'), - }; - }), - ); - } -} diff --git a/projects/gfbio-app/src/app/users/user.service.ts b/projects/gfbio-app/src/app/users/user.service.ts deleted file mode 100644 index efc86922..00000000 --- a/projects/gfbio-app/src/app/users/user.service.ts +++ /dev/null @@ -1,129 +0,0 @@ -import {Inject, Injectable} from '@angular/core'; -import {HttpClient} from '@angular/common/http'; - -import {Observable} from 'rxjs'; -import {map, switchMap} from 'rxjs/operators'; - -import {Config, MappingRequestParameters, NotificationService, ParametersType, UserService} from 'wave-core'; - -import {AppConfig} from '../app-config.service'; -import {AbcdArchive} from '../operators/dialogs/abcd-repository/abcd.model'; -import {Basket} from '../operators/dialogs/baskets/gfbio-basket.model'; -import {CsvColumn} from '../operators/dialogs/baskets/csv.model'; - -@Injectable() -export class GFBioUserService extends UserService { - constructor( - @Inject(Config) protected readonly config: AppConfig, - protected readonly http: HttpClient, - protected readonly notificationService: NotificationService, - ) { - super(config, http, notificationService); - } - - /** - * Get the schema of a source operator. TODO: this should be replaced by a generic service call, which resolves the shema of a source. - */ - getSourceSchemaAbcd(): Observable> { - const jsonUrl = './assets/abcd-mandatory-fields.json'; - - return this.http.get>(jsonUrl); - } - - /** - * Get as stream of Abcd sources depending on the logged in user. - */ - getAbcdArchivesStream(): Observable> { - interface AbcdResponse { - archives: Array; - result: boolean; - } - - return super.getSessionStream().pipe( - switchMap((session) => { - const parameters = new GfbioServiceRequestParameters({ - request: 'abcd', - sessionToken: session.sessionToken, - }); - return super.request(parameters).pipe(map((abcdResponse) => abcdResponse.archives)); - }), - ); - } - - /** - * Get as stream of GFBio baskets sources depending on the logged in user. - */ - getGfbioBasketStream(): Observable> { - interface GfbioBasketResponse { - baskets: Array; - result: boolean; - } - - return super.getSessionStream().pipe( - switchMap((session) => { - const parameters = new GfbioServiceRequestParameters({ - request: 'baskets', - sessionToken: session.sessionToken, - }); - return super.request(parameters).pipe(map((gfbioBasketResponse) => gfbioBasketResponse.baskets)); - }), - ); - } - - /** - * Login using an OpenId Connect access token - * - * @returns `true` if the login was succesful, `false` otherwise. - */ - oidcLogin(accessToken: string): Observable { - const parameters = new OidcServiceRequestParameters({ - sessionToken: undefined, - request: 'login', - parameters: {access_token: accessToken}, - }); - - return super.loginRequestToUserDetails(parameters); - } - - /** - * Redirect current app to SSO page - */ - redirectToOidcProvider(payload?: string) { - const url = this.config.GFBIO.SSO.URL; - const client_id = this.config.GFBIO.SSO.CLIENT_ID; - const scope = this.config.GFBIO.SSO.SCOPE; - const state = payload ? `&state=${encodeURIComponent(payload)}` : ''; - window.location.href = `${url}?client_id=${client_id}&response_type=token&scope=${scope}${state}`; - } - - setIntroductoryPopup(show: boolean) { - localStorage.setItem('showIntroductoryPopup', JSON.stringify(show)); - } - - shouldShowIntroductoryPopup(): boolean { - const show = localStorage.getItem('showIntroductoryPopup'); - return show === null || JSON.parse(show); - } -} - -class GfbioServiceRequestParameters extends MappingRequestParameters { - constructor(config: {request: string; sessionToken: string; parameters?: ParametersType}) { - super({ - service: 'gfbio', - request: config.request, - sessionToken: config.sessionToken, - parameters: config.parameters, - }); - } -} - -class OidcServiceRequestParameters extends MappingRequestParameters { - constructor(config: {request: string; sessionToken: string; parameters?: ParametersType}) { - super({ - service: 'oidc', - request: config.request, - sessionToken: config.sessionToken, - parameters: config.parameters, - }); - } -} diff --git a/projects/gfbio-app/src/assets/.gitignore b/projects/gfbio-app/src/assets/.gitignore deleted file mode 100644 index d344ba6b..00000000 --- a/projects/gfbio-app/src/assets/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.json diff --git a/projects/gfbio-app/src/assets/.gitkeep b/projects/gfbio-app/src/assets/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/gfbio-app/src/assets/abcd-mandatory-fields.json b/projects/gfbio-app/src/assets/abcd-mandatory-fields.json deleted file mode 100644 index 4b44ac32..00000000 --- a/projects/gfbio-app/src/assets/abcd-mandatory-fields.json +++ /dev/null @@ -1,290 +0,0 @@ -[ - { - "name": "/DataSets/DataSet/DatasetGUID", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/TechnicalContacts/TechnicalContact/Name", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/TechnicalContacts/TechnicalContact/Email", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/ContentContacts/ContentContact/Name", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/ContentContacts/ContentContact/Email", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Metadata/Description/Representation/Title", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Metadata/Description/Representation/Details", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Metadata/Description/Representation/URI", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Metadata/RevisionData/DateModified", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Metadata/IPRStatements/Licenses/License/Text", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Metadata/IPRStatements/Citations/Citation/Text", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Metadata/IPRStatements/Licenses/License/Details", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Metadata/IPRStatements/Licenses/License/URI", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": true, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/SourceInstitutionID", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/SourceID", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/UnitID", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/DateLastEdited", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Identifications/Identification/Result/TaxonIdentified/HigherTaxa/HigherTaxon/HigherTaxonName", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Identifications/Identification/Result/TaxonIdentified/HigherTaxa/HigherTaxon/HigherTaxonRank", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Identifications/Identification/Result/TaxonIdentified/ScientificName/FullScientificNameString", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/RecordBasis", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/MultiMediaObjects/MultiMediaObject/FileURI", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/MultiMediaObjects/MultiMediaObject/Format", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/MultiMediaObjects/MultiMediaObject/IPR/Licenses/License/Text", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/MultiMediaObjects/MultiMediaObject/IPR/Licenses/License/Details", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/MultiMediaObjects/MultiMediaObject/IPR/Licenses/License/URI", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/MultiMediaObjects/MultiMediaObject/Creator", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Gathering/DateTime/ISODateTimeBegin", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Gathering/Agents/GatheringAgent/AgentText", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Gathering/LocalityText", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Gathering/Country/Name", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Gathering/Country/ISO3166Code", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": false, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Gathering/SiteCoordinateSets/SiteCoordinates/CoordinatesLatLong/LongitudeDecimal", - "numeric": true, - "vatMandatory": true, - "gfbioMandatory": true, - "globalField": false, - "unit": "°" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Gathering/SiteCoordinateSets/SiteCoordinates/CoordinatesLatLong/LatitudeDecimal", - "numeric": true, - "vatMandatory": true, - "gfbioMandatory": true, - "globalField": false, - "unit": "°" - }, - { - "name": "/DataSets/DataSet/Units/Unit/Gathering/SiteCoordinateSets/SiteCoordinates/CoordinatesLatLong/SpatialDatum", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - }, - { - "name": "/DataSets/DataSet/Units/Unit/RecordURI", - "numeric": false, - "vatMandatory": false, - "gfbioMandatory": true, - "globalField": false, - "unit": "" - } -] diff --git a/projects/gfbio-app/src/assets/logo_gfbio.png b/projects/gfbio-app/src/assets/logo_gfbio.png deleted file mode 100644 index 6f68f04b..00000000 Binary files a/projects/gfbio-app/src/assets/logo_gfbio.png and /dev/null differ diff --git a/projects/gfbio-app/src/assets/widget.xml b/projects/gfbio-app/src/assets/widget.xml deleted file mode 100644 index 9b5743ab..00000000 --- a/projects/gfbio-app/src/assets/widget.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - // get preferences - var prefs = new gadgets.Prefs(); - - // size application - var totalHeight = isNaN(parent.window.innerHeight) ? parent.window.clientHeight : parent.window.innerHeight; - var headerHeight = prefs.getInt("HEADER_HEIGHT"); - gadgets.window.adjustHeight(totalHeight - headerHeight); - - // get url params - var urlParams = parent.window.location.search - - // create iframe - var iframe = document.createElement('iframe'); - iframe.id = 'searchVisualizationFrame'; - iframe.style.border = 'none'; - iframe.style.margin = 0; - iframe.style.padding = 0; - iframe.style.height = '100%'; - iframe.style.width = '100%'; - iframe.src = prefs.getString('VAT_URL') + '#/' + urlParams; - - // listen on load event and then send the token - function forwardToken(event) { - var message = event.data; - if (message.type === 'STATUS' && message.status === 'READY') { - parent.Liferay.Service( - '/GFBioProject-portlet.basket/get-token', - function (token) { - iframe.contentWindow.postMessage({type: 'TOKEN_LOGIN', token: token}, '*'); - } - ); - } - } - - window.addEventListener('message', forwardToken); - - // append iframe to document body - document.getElementsByTagName('body')[0].appendChild(iframe); - - ]]> - - diff --git a/projects/gfbio-app/src/environments/environment.prod.ts b/projects/gfbio-app/src/environments/environment.prod.ts deleted file mode 100644 index da7c84f6..00000000 --- a/projects/gfbio-app/src/environments/environment.prod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: true, -}; diff --git a/projects/gfbio-app/src/environments/environment.ts b/projects/gfbio-app/src/environments/environment.ts deleted file mode 100644 index c9cad009..00000000 --- a/projects/gfbio-app/src/environments/environment.ts +++ /dev/null @@ -1,16 +0,0 @@ -// This file can be replaced during build by using the `fileReplacements` array. -// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. -// The list of file replacements can be found in `angular.json`. - -export const environment = { - production: false, -}; - -/* - * For easier debugging in development mode, you can import the following file - * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. - * - * This import should be commented out in production mode because it will have a negative impact - * on performance if an error is thrown. - */ -// import 'zone.js/dist/zone-error'; // Included with Angular CLI. diff --git a/projects/gfbio-app/src/favicon.ico b/projects/gfbio-app/src/favicon.ico deleted file mode 100644 index e2cef5c7..00000000 Binary files a/projects/gfbio-app/src/favicon.ico and /dev/null differ diff --git a/projects/gfbio-app/src/index.html b/projects/gfbio-app/src/index.html deleted file mode 100644 index d7a9715d..00000000 --- a/projects/gfbio-app/src/index.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - VAT: Visualization, Analysis and Transformation System - - - - - - - -

VAT

-
- · - · - · -
-
- - diff --git a/projects/gfbio-app/src/main.ts b/projects/gfbio-app/src/main.ts deleted file mode 100644 index 469eddb3..00000000 --- a/projects/gfbio-app/src/main.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {enableProdMode} from '@angular/core'; -import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; - -import {AppModule} from './app/app.module'; -import {environment} from './environments/environment'; - -if (environment.production) { - enableProdMode(); -} - -platformBrowserDynamic() - .bootstrapModule(AppModule) - .catch((err) => console.error(err)); diff --git a/projects/gfbio-app/src/polyfills.ts b/projects/gfbio-app/src/polyfills.ts deleted file mode 100644 index e49856ec..00000000 --- a/projects/gfbio-app/src/polyfills.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), - * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - -/*************************************************************************************************** - * BROWSER POLYFILLS - */ - -/** IE10 and IE11 requires the following for NgClass support on SVG elements */ -// import 'classlist.js'; // Run `npm install --save classlist.js`. - -/** - * Web Animations `@angular/platform-browser/animations` - * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. - * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). - */ -// import 'web-animations-js'; // Run `npm install --save web-animations-js`. - -/** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before `zone.js` being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass `zone.js` patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - -/*************************************************************************************************** - * Zone JS is required by default for Angular itself. - */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ diff --git a/projects/gfbio-app/src/styles.scss b/projects/gfbio-app/src/styles.scss deleted file mode 100644 index cf2f195d..00000000 --- a/projects/gfbio-app/src/styles.scss +++ /dev/null @@ -1,22 +0,0 @@ -@import 'app-theme'; - -:root { - --wave-primary-color: #{mat-color($wave-app-primary)}; - --wave-accent-color: #{mat-color($wave-app-accent)}; - --wave-warn-color: #{mat-color($wave-app-warn)}; - - --wave-faded-accent-color: #{mat-color($wave-app-accent, 0.32)}; - - --wave-foreground-text-color: #{mat-color(map-get($wave-app-theme, foreground), text)}; - --wave-foreground-secondary-text-color: #{mat-color(map-get($wave-app-theme, foreground), secondary-text)}; - - --wave-background-color: #{map-get(map-get($wave-app-theme, background), background)}; - --wave-background-hover-color: #{mat-color(map-get($wave-app-theme, background), hover)}; - - font-family: Roboto, 'Helvetica Neue', sans-serif; - font-size: 16px; -} - -a { - color: mat-color(map-get($wave-app-theme, foreground), secondary-text); -} diff --git a/projects/gfbio-app/src/test.ts b/projects/gfbio-app/src/test.ts deleted file mode 100644 index 7a816b2b..00000000 --- a/projects/gfbio-app/src/test.ts +++ /dev/null @@ -1,23 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files - -import 'zone.js/dist/zone-testing'; -import {getTestBed} from '@angular/core/testing'; -import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing'; - -declare const require: { - context( - path: string, - deep?: boolean, - filter?: RegExp, - ): { - keys(): string[]; - (id: string): T; - }; -}; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().map(context); diff --git a/projects/gfbio-app/tsconfig.app.json b/projects/gfbio-app/tsconfig.app.json deleted file mode 100644 index 8212f985..00000000 --- a/projects/gfbio-app/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/app", - "types": [] - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": [], - "paths": { - "wave-core": ["dist/wave-core"] - } -} diff --git a/projects/gfbio-app/tsconfig.spec.json b/projects/gfbio-app/tsconfig.spec.json deleted file mode 100644 index b6b4f089..00000000 --- a/projects/gfbio-app/tsconfig.spec.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] -} diff --git a/projects/nature40-app/.eslintrc.json b/projects/nature40-app/.eslintrc.json deleted file mode 100644 index ff3b48ea..00000000 --- a/projects/nature40-app/.eslintrc.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": [ - "projects/nature40-app/tsconfig.app.json", - "projects/nature40-app/tsconfig.spec.json", - "projects/nature40-app/e2e/tsconfig.json" - ], - "createDefaultProgram": true - }, - "rules": {} - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/nature40-app/browserslist b/projects/nature40-app/browserslist deleted file mode 100644 index 80848532..00000000 --- a/projects/nature40-app/browserslist +++ /dev/null @@ -1,12 +0,0 @@ -# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. -# For additional information regarding the format and rule options, please see: -# https://github.com/browserslist/browserslist#queries - -# You can see what browsers were selected by your queries by running: -# npx browserslist - -> 0.5% -last 2 versions -Firefox ESR -not dead -not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/projects/nature40-app/e2e/protractor.conf.js b/projects/nature40-app/e2e/protractor.conf.js deleted file mode 100644 index bf4376ef..00000000 --- a/projects/nature40-app/e2e/protractor.conf.js +++ /dev/null @@ -1,30 +0,0 @@ -// @ts-check -// Protractor configuration file, see link for more information -// https://github.com/angular/protractor/blob/master/lib/config.ts - -const {SpecReporter} = require('jasmine-spec-reporter'); - -/** - * @type { import("protractor").Config } - */ -exports.config = { - allScriptsTimeout: 11000, - specs: ['./src/**/*.e2e-spec.ts'], - capabilities: { - browserName: 'chrome', - }, - directConnect: true, - baseUrl: 'http://localhost:4200/', - framework: 'jasmine', - jasmineNodeOpts: { - showColors: true, - defaultTimeoutInterval: 30000, - print: function () {}, - }, - onPrepare() { - require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json'), - }); - jasmine.getEnv().addReporter(new SpecReporter({spec: {displayStacktrace: true}})); - }, -}; diff --git a/projects/nature40-app/e2e/src/app.e2e-spec.ts b/projects/nature40-app/e2e/src/app.e2e-spec.ts deleted file mode 100644 index 53905473..00000000 --- a/projects/nature40-app/e2e/src/app.e2e-spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {AppPage} from './app.po'; -import {browser, logging} from 'protractor'; - -describe('workspace-project App', () => { - let page: AppPage; - - beforeEach(() => { - page = new AppPage(); - }); - - it('should display welcome message', () => { - page.navigateTo(); - expect(page.getTitleText()).toEqual('nature40-app app is running!'); - }); - - afterEach(async () => { - // Assert that there are no errors emitted from the browser - const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain( - jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry), - ); - }); -}); diff --git a/projects/nature40-app/e2e/src/app.po.ts b/projects/nature40-app/e2e/src/app.po.ts deleted file mode 100644 index 02d41cfc..00000000 --- a/projects/nature40-app/e2e/src/app.po.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {browser, by, element} from 'protractor'; - -export class AppPage { - navigateTo(): Promise { - return browser.get(browser.baseUrl) as Promise; - } - - getTitleText(): Promise { - return element(by.css('wave-nature40-root .content span')).getText() as Promise; - } -} diff --git a/projects/nature40-app/e2e/tsconfig.json b/projects/nature40-app/e2e/tsconfig.json deleted file mode 100644 index 3d39212b..00000000 --- a/projects/nature40-app/e2e/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "outDir": "../../../out-tsc/e2e", - "module": "commonjs", - "target": "es5", - "types": ["jasmine", "jasminewd2", "node"] - } -} diff --git a/projects/nature40-app/karma.conf.js b/projects/nature40-app/karma.conf.js deleted file mode 100644 index 293c8f8c..00000000 --- a/projects/nature40-app/karma.conf.js +++ /dev/null @@ -1,32 +0,0 @@ -// Karma configuration file, see link for more information -// https://karma-runner.github.io/1.0/config/configuration-file.html - -module.exports = function (config) { - config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], - plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage-istanbul-reporter'), - require('@angular-devkit/build-angular/plugins/karma'), - ], - client: { - clearContext: false, // leave Jasmine Spec Runner output visible in browser - }, - coverageIstanbulReporter: { - dir: require('path').join(__dirname, '../../coverage/nature40-app'), - reports: ['html', 'lcovonly', 'text-summary'], - fixWebpackSourcePaths: true, - }, - reporters: ['progress', 'kjhtml'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome'], - singleRun: false, - restartOnFileChange: true, - }); -}; diff --git a/projects/nature40-app/src/app-theme.scss b/projects/nature40-app/src/app-theme.scss deleted file mode 100644 index 3a2a934c..00000000 --- a/projects/nature40-app/src/app-theme.scss +++ /dev/null @@ -1,181 +0,0 @@ -@import '~@angular/material/theming'; - -// Material Base Styles -@include mat-core(); - -// Define Colors -$nature40-green: ( - 50: #e1ede8, - 100: #b4d2c5, - 200: #82b59e, - 300: #4f9777, - 400: #2a8059, - 500: #046a3c, - 600: #036236, - 700: #03572e, - 800: #024d27, - 900: #013c1a, - A100: #72ff9f, - A200: #3fff7c, - A400: #0cff59, - A700: #00f14d, - contrast: ( - 50: #000000, - 100: #000000, - 200: #000000, - 300: #ffffff, - 400: #ffffff, - 500: #ffffff, - 600: #ffffff, - 700: #ffffff, - 800: #ffffff, - 900: #ffffff, - A100: #000000, - A200: #000000, - A400: #000000, - A700: #000000, - ), -); - -$nature40-orange: ( - 50: #fef3e1, - 100: #fce2b4, - 200: #facf82, - 300: #f7bb4f, - 400: #f6ad2a, - 500: #f49e04, - 600: #f39603, - 700: #f18c03, - 800: #ef8202, - 900: #ec7001, - A100: #ffffff, - A200: #ffede0, - A400: #ffcfad, - A700: #ffc093, - contrast: ( - 50: #000000, - 100: #000000, - 200: #000000, - 300: #000000, - 400: #000000, - 500: #000000, - 600: #000000, - 700: #000000, - 800: #000000, - 900: #000000, - A100: #000000, - A200: #000000, - A400: #000000, - A700: #000000, - ), -); - -$nature40-blue: ( - 50: #e1e2f1, - 100: #b4b7dd, - 200: #8287c6, - 300: #4f56af, - 400: #2a329d, - 500: #040e8c, - 600: #030c84, - 700: #030a79, - 800: #02086f, - 900: #01045c, - A100: #8d8dff, - A200: #5a5aff, - A400: #2727ff, - A700: #0e0eff, - contrast: ( - 50: #000000, - 100: #000000, - 200: #000000, - 300: #ffffff, - 400: #ffffff, - 500: #ffffff, - 600: #ffffff, - 700: #ffffff, - 800: #ffffff, - 900: #ffffff, - A100: #000000, - A200: #ffffff, - A400: #ffffff, - A700: #ffffff, - ), -); - -$nature40-lightgreen: ( - 50: #f4f9f1, - 100: #e4f0dd, - 200: #d2e7c6, - 300: #bfddaf, - 400: #b2d59d, - 500: #a4ce8c, - 600: #9cc984, - 700: #92c279, - 800: #89bc6f, - 900: #78b05c, - A100: #ffffff, - A200: #efffe7, - A400: #ccffb4, - A700: #bbff9b, - contrast: ( - 50: #000000, - 100: #000000, - 200: #000000, - 300: #000000, - 400: #000000, - 500: #000000, - 600: #000000, - 700: #000000, - 800: #000000, - 900: #000000, - A100: #000000, - A200: #000000, - A400: #000000, - A700: #000000, - ), -); - -$nature40-gray: ( - 50: #efefef, - 100: #d8d8d8, - 200: #bebebe, - 300: #a3a3a3, - 400: #909090, - 500: #7c7c7c, - 600: #747474, - 700: #696969, - 800: #5f5f5f, - 900: #4c4c4c, - A100: #bababa, - A200: #8c8c8c, - A400: #4d4d4d, - A700: #333333, - contrast: ( - 50: #000000, - 100: #000000, - 200: #000000, - 300: #000000, - 400: #000000, - 500: #ffffff, - 600: #ffffff, - 700: #ffffff, - 800: #ffffff, - 900: #ffffff, - A100: #000000, - A200: #000000, - A400: #000000, - A700: #ffffff, - ), -); - -// Define App Theme -$wave-app-primary: mat-palette($nature40-green); -$wave-app-accent: mat-palette($nature40-orange, A200, A100, A400); -$wave-app-warn: mat-palette($mat-red); - -// Create the theme object (a Sass map containing all of the palettes). -$wave-app-theme: mat-light-theme($wave-app-primary, $wave-app-accent, $wave-app-warn); - -// Apply Angular Material Mixin to Color Theme -@include angular-material-theme($wave-app-theme); diff --git a/projects/nature40-app/src/app/app-config.service.ts b/projects/nature40-app/src/app/app-config.service.ts deleted file mode 100644 index e3f72a6c..00000000 --- a/projects/nature40-app/src/app/app-config.service.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {Injectable} from '@angular/core'; -import {mergeDeep} from 'immutable'; -import {Config, WaveConfigStructure, WAVE_DEFAULT_CONFIG} from 'wave-core'; - -interface Nature40 { - SSO_JWT_PROVIDER_URL: string; - DEFAULT_VIEW_BBOX: [number, number, number, number]; -} - -interface AppConfigStructure extends WaveConfigStructure { - readonly NATURE40: Nature40; -} - -const APP_CONFIG_DEFAULTS = mergeDeep(WAVE_DEFAULT_CONFIG, { - NATURE40: { - SSO_JWT_PROVIDER_URL: 'http://vhrz669.hrz.uni-marburg.de/nature40/sso?jws=', - DEFAULT_VIEW_BBOX: [8.66, 50.82, 8.69, 50.84], // default to Uniwald - }, -}) as AppConfigStructure; - -@Injectable() -export class AppConfig extends Config { - protected config: AppConfigStructure; - - get NATURE40(): Nature40 { - return this.config.NATURE40; - } - - load(): Promise { - return super.load(APP_CONFIG_DEFAULTS); - } -} diff --git a/projects/nature40-app/src/app/app.component.html b/projects/nature40-app/src/app/app.component.html deleted file mode 100644 index 8ea86bf8..00000000 --- a/projects/nature40-app/src/app/app.component.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - -
- - -
- -
- - - - - -
- - - - - - - - - - - - - - - - -
-
- - - - -
Data Table
-
- - -
- - -
Citations
-
- - -
-
-
-
diff --git a/projects/nature40-app/src/app/app.component.scss b/projects/nature40-app/src/app/app.component.scss deleted file mode 100644 index 6c793ea9..00000000 --- a/projects/nature40-app/src/app/app.component.scss +++ /dev/null @@ -1,119 +0,0 @@ -wave-navigation { - z-index: 10; -} - -wave-layer-list { - position: absolute; - z-index: 2; - width: 16vw; - min-width: 200px; - left: 0; - top: 0; - background-color: rgba(255, 255, 255, 0.87); - border-bottom-right-radius: 2px; - - .logo { - filter: hue-rotate(270deg); - } -} - -.time-container { - position: absolute; - left: 16vw; - right: 16vw; - - wave-ticker-interaction, - wave-small-time-interaction, - wave-zoom-handles { - background-color: rgba(255, 255, 255, 0.87); - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; - z-index: 3; - } -} - -:host ::ng-deep .mat-sidenav-content { - overflow: hidden; -} - -.top-container { - z-index: 1; -} - -.mid-container { - z-index: 0; - position: relative; -} - -.bottom-container { - position: relative; - z-index: 1; - - min-height: 3rem; - @media (max-width: 600px) and (orientation: portrait) { - min-height: 2.5rem; - } - @media (max-width: 960px) and (orientation: landscape) { - min-height: 2rem; - } - - .toggle { - position: absolute; - z-index: 1; - padding: 0; - min-width: 3rem; - width: 3rem; - height: 3rem; - @media (max-width: 600px) and (orientation: portrait) { - min-width: 2.5rem; - width: 2.5rem; - height: 2.5rem; - } - @media (max-width: 960px) and (orientation: landscape) { - min-width: 2rem; - width: 2rem; - height: 2rem; - } - } - - ::ng-deep .mat-tab-label-container { - margin-left: 3rem; - @media (max-width: 600px) and (orientation: portrait) { - margin-left: 2.5rem; - } - @media (max-width: 960px) and (orientation: landscape) { - margin-left: 2rem; - } - } - - @media (max-width: 960px) and (orientation: landscape) { - ::ng-deep mat-tab-header { - height: 2rem; - } - ::ng-deep .mat-tab-label { - line-height: 2rem; - } - } - @media (max-width: 600px) and (orientation: portrait) { - ::ng-deep mat-tab-header { - height: 2.5rem; - } - ::ng-deep .mat-tab-label { - line-height: 2.5rem; - } - } -} - -.bottom-container.small { - max-height: 3rem !important; - @media (max-width: 600px) and (orientation: portrait) { - max-height: 2.5rem !important; - } - @media (max-width: 960px) and (orientation: landscape) { - max-height: 2rem !important; - } - - ::ng-deep mat-tab-header { - border: 0; - } -} diff --git a/projects/nature40-app/src/app/app.component.ts b/projects/nature40-app/src/app/app.component.ts deleted file mode 100644 index a5f40853..00000000 --- a/projects/nature40-app/src/app/app.component.ts +++ /dev/null @@ -1,364 +0,0 @@ -import {Observable, BehaviorSubject, fromEvent} from 'rxjs'; -import {map, tap, first} from 'rxjs/operators'; - -import {transformExtent} from 'ol/proj'; - -import { - AfterViewInit, - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - HostListener, - Inject, - OnInit, - ViewChild, - ViewContainerRef, -} from '@angular/core'; -import {MatDialog} from '@angular/material/dialog'; -import {MatIconRegistry} from '@angular/material/icon'; -import {MatSidenav} from '@angular/material/sidenav'; -import {MatTabGroup} from '@angular/material/tabs'; -import { - Layer, - SidenavContainerComponent, - MapContainerComponent, - AbstractSymbology, - LayerService, - LayoutService, - ProjectService, - UserService, - StorageService, - RandomColorService, - MappingQueryService, - NotificationService, - MapService, - Config, - ResultTypes, - PlotListComponent, - WorkflowParameterChoiceDialogComponent, - NavigationButton, - SourceOperatorListComponent, - NavigationComponent, - OperatorListComponent, - TimeConfigComponent, - WorkspaceSettingsComponent, - HelpComponent, - SourceOperatorListButton, - GFBioSourceType, - GbifOperatorComponent, - OperatorListButtonGroups, - SidenavConfig, - Projections, -} from 'wave-core'; -import {DomSanitizer} from '@angular/platform-browser'; -import {ActivatedRoute} from '@angular/router'; -import {AppConfig} from './app-config.service'; -import {Nature40UserService} from './users/nature40-user.service'; -import {LoginComponent} from './users/login/login.component'; -import {Nature40CatalogComponent} from './operators/dialogs/nature40-catalog/nature40-catalog.component'; - -@Component({ - selector: 'wave-nature40-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AppComponent implements OnInit, AfterViewInit { - @ViewChild(MapContainerComponent, {static: true}) mapComponent: MapContainerComponent; - @ViewChild(MatTabGroup, {static: true}) bottomTabs: MatTabGroup; - - @ViewChild(MatSidenav, {static: true}) rightSidenav: MatSidenav; - @ViewChild(SidenavContainerComponent, {static: true}) rightSidenavContainer: SidenavContainerComponent; - - readonly ResultTypes = ResultTypes; - readonly LayoutService = LayoutService; - - readonly layersReverse$: Observable>>; - readonly layerListVisible$: Observable; - readonly layerDetailViewVisible$: Observable; - - readonly navigationButtons = this.setupNavigation(); - readonly addAFirstLayerConfig = AppComponent.setupAddDataConfig(); - - middleContainerHeight$: Observable; - bottomContainerHeight$: Observable; - mapIsGrid$: Observable; - - private windowHeight$ = new BehaviorSubject(window.innerHeight); - - constructor( - @Inject(Config) readonly config: AppConfig, - readonly layerService: LayerService, - readonly layoutService: LayoutService, - readonly projectService: ProjectService, - readonly vcRef: ViewContainerRef, // reference used by color picker - @Inject(UserService) private readonly userService: Nature40UserService, - private storageService: StorageService, - private changeDetectorRef: ChangeDetectorRef, - private dialog: MatDialog, - private iconRegistry: MatIconRegistry, - private randomColorService: RandomColorService, - private mappingQueryService: MappingQueryService, - private activatedRoute: ActivatedRoute, - private notificationService: NotificationService, - private mapService: MapService, - private sanitizer: DomSanitizer, - ) { - this.registerIcons(); - - vcRef.length; // eslint-disable-line @typescript-eslint/no-unused-expressions - - this.storageService.toString(); // just register - - this.layersReverse$ = this.projectService.getLayerStream().pipe(map((layers) => layers.slice(0).reverse())); - - this.layerListVisible$ = this.layoutService.getLayerListVisibilityStream(); - this.layerDetailViewVisible$ = this.layoutService.getLayerDetailViewVisibilityStream(); - - this.setupInitialZoom(); - } - - private registerIcons() { - this.iconRegistry.addSvgIconInNamespace('vat', 'logo', this.sanitizer.bypassSecurityTrustResourceUrl('assets/vat_logo.svg')); - - // used for navigation - this.iconRegistry.addSvgIcon('cogs', this.sanitizer.bypassSecurityTrustResourceUrl('assets/icons/cogs.svg')); - - this.iconRegistry.addSvgIconInNamespace( - 'nature40', - 'icon', - this.sanitizer.bypassSecurityTrustResourceUrl('assets/icons/natur_40_logo.svg'), - ); - } - - ngOnInit() { - this.mapService.registerMapComponent(this.mapComponent); - this.mapIsGrid$ = this.mapService.isGrid$; - - this.middleContainerHeight$ = this.layoutService.getMapHeightStream(this.windowHeight$).pipe(tap(() => this.mapComponent.resize())); - this.bottomContainerHeight$ = this.layoutService.getLayerDetailViewStream(this.windowHeight$); - } - - ngAfterViewInit() { - this.layoutService.getSidenavContentComponentStream().subscribe((sidenavConfig) => { - this.rightSidenavContainer.load(sidenavConfig); - if (sidenavConfig) { - this.rightSidenav.open(); - } else { - this.rightSidenav.close(); - } - }); - this.projectService - .getNewPlotStream() - .subscribe(() => this.layoutService.setSidenavContentComponent({component: PlotListComponent})); - - // set the stored tab index - this.layoutService.getLayerDetailViewTabIndexStream().subscribe((tabIndex) => { - if (this.bottomTabs.selectedIndex !== tabIndex) { - this.bottomTabs.selectedIndex = tabIndex; - setTimeout(() => this.changeDetectorRef.markForCheck()); - } - }); - - this.handleQueryParameters(); - } - - setTabIndex(index: number) { - this.layoutService.setLayerDetailViewTabIndex(index); - this.layoutService.setLayerDetailViewVisibility(true); - } - - private setupNavigation(): Array { - return [ - NavigationComponent.createLoginButton(this.userService, this.layoutService, this.config, {component: LoginComponent}), - { - sidenavConfig: AppComponent.setupAddDataConfig(), - icon: 'add', - tooltip: 'Add Data', - }, - { - sidenavConfig: AppComponent.setupOperatorListConfig(), - icon: '', - svgIcon: 'cogs', - tooltip: 'Operators', - }, - { - sidenavConfig: {component: PlotListComponent, config: {operatorsListConfig: AppComponent.setupOperatorListConfig()}}, - icon: 'equalizer', - tooltip: 'Plots', - }, - { - sidenavConfig: {component: TimeConfigComponent}, - icon: 'access_time', - tooltip: 'Time', - }, - { - sidenavConfig: {component: WorkspaceSettingsComponent}, - icon: 'settings', - tooltip: 'Workspace', - }, - { - sidenavConfig: {component: HelpComponent}, - icon: 'help', - tooltip: 'Help', - }, - ]; - } - - private static setupAddDataConfig(): SidenavConfig { - return {component: SourceOperatorListComponent, config: {buttons: AppComponent.createSourceOperatorListButtons()}}; - } - - private static setupOperatorListConfig(): SidenavConfig { - return {component: OperatorListComponent, config: {operators: AppComponent.createOperatorListButtons()}}; - } - - private static createSourceOperatorListButtons(): Array { - return [ - SourceOperatorListComponent.createDataRepositoryButton(), - { - name: 'Nature 4.0 Catalog', - description: 'Browse all the Nature 4.0 data', - icon: 'nature_people', - sidenavConfig: {component: Nature40CatalogComponent, keepParent: true}, - onlyIfLoggedIn: true, - }, - { - name: 'Nature 4.0 Catalog', - description: 'Log in to browse all the Nature 4.0 data', - icon: 'nature_people', - sidenavConfig: undefined, - onlyIfLoggedOut: true, - }, - SourceOperatorListComponent.createDrawFeaturesButton(), - ...SourceOperatorListComponent.createCustomFeaturesButtons(), - { - name: 'Species Occurrences', - description: 'Query data from GBIF', - iconSrc: GFBioSourceType.ICON_URL, - sidenavConfig: {component: GbifOperatorComponent, keepParent: true}, - }, - SourceOperatorListComponent.createCountryPolygonsButton(), - ]; - } - - private static createOperatorListButtons(): OperatorListButtonGroups { - return [ - {name: 'Mixed', list: OperatorListComponent.DEFAULT_MIXED_OPERATOR_DIALOGS}, - {name: 'Plots', list: OperatorListComponent.DEFAULT_PLOT_OPERATOR_DIALOGS}, - {name: 'Raster', list: OperatorListComponent.DEFAULT_RASTER_OPERATOR_DIALOGS}, - {name: 'Vector', list: OperatorListComponent.DEFAULT_VECTOR_OPERATOR_DIALOGS}, - ]; - } - - @HostListener('window:resize') - private windowHeight() { - this.windowHeight$.next(window.innerHeight); - } - - private handleQueryParameters() { - this.activatedRoute.queryParams.subscribe((p) => { - for (const parameter of Object.keys(p)) { - const value = p[parameter]; - switch (parameter) { - case 'workflow': - try { - const newLayer = Layer.fromDict(JSON.parse(value)); - this.projectService - .getProjectStream() - .pipe(first()) - .subscribe((project) => { - if (project.layers.length > 0) { - // show popup - this.dialog.open(WorkflowParameterChoiceDialogComponent, { - data: { - dialogTitle: 'Workflow URL Parameter', - sourceName: 'URL parameter', - layers: [newLayer], - nonAvailableNames: [], - numberOfLayersInProject: project.layers.length, - }, - }); - } else { - // just add the layer if the layer array is empty - this.projectService.addLayer(newLayer); - } - }); - } catch (error) { - this.notificationService.error(`Invalid Workflow: »${error}«`); - } - break; - case 'jws': - case 'jwt': - this.nature40JwtLogin(parameter, value); - break; - default: - this.notificationService.error(`Unknown URL Parameter »${parameter}«`); - } - } - }); - } - - private nature40JwtLogin(parameter: string, token: string) { - this.userService - .nature40JwtTokenLogin(token) - .pipe(first()) - .subscribe( - (success) => { - if (success) { - this.notificationService.info(`Logged in using ${parameter.toUpperCase()}`); - } else { - this.notificationService.error(`Login with ${parameter.toUpperCase()} unsuccessful`); - // log out, because mapping session exists, but JWT token has become invalid - this.userService.guestLogin().pipe(first()).subscribe(); - } - }, - (error) => { - this.notificationService.error(`Cant handle provided ${parameter.toUpperCase()} parameters: »${error}«`); - }, - ); - } - - /** - * This handler stores the user viewport extent on leaving the app and retrieves it the next time. - * The data is stored in local storage, s.th. it is not reflected using multiple browsers. - * If there is no extent stored it uses the *Uniwald* extent as a starting point. - */ - private setupInitialZoom() { - const PATH_PREFIX = window.location.pathname.replace(/\//g, '_').replace(/-/g, '_'); - const storage_key = `${PATH_PREFIX}_zoom_extent`; - - let stored_extent: [number, number, number, number] = JSON.parse(localStorage.getItem(storage_key)); - - if (!stored_extent) { - stored_extent = this.config.NATURE40.DEFAULT_VIEW_BBOX; - } - - this.projectService - .getProjectionStream() - .pipe(first()) - .subscribe((projection) => { - const projectedExtent = transformExtent( - stored_extent, - Projections.WGS_84.getOpenlayersProjection(), - projection.getOpenlayersProjection(), - ); - this.mapService.zoomTo(projectedExtent); - }); - - fromEvent(window, 'beforeunload').subscribe(() => { - // store extent when leaving the site - this.projectService - .getProjectionStream() - .pipe(first()) - .subscribe((projection) => { - const wgs84_extent: [number, number, number, number] = transformExtent( - this.mapService.getViewportSize().extent, - projection.getOpenlayersProjection(), - Projections.WGS_84.getOpenlayersProjection(), - ); - localStorage.setItem(storage_key, JSON.stringify(wgs84_extent)); - }); - }); - } -} diff --git a/projects/nature40-app/src/app/app.module.ts b/projects/nature40-app/src/app/app.module.ts deleted file mode 100644 index 4a5685b6..00000000 --- a/projects/nature40-app/src/app/app.module.ts +++ /dev/null @@ -1,58 +0,0 @@ -import {APP_INITIALIZER, NgModule} from '@angular/core'; -import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; -import {BrowserModule} from '@angular/platform-browser'; -import {HttpClientModule} from '@angular/common/http'; -import {RouterModule} from '@angular/router'; - -import {AppComponent} from './app.component'; -import { - Config, - LayerService, - LayoutService, - MappingQueryService, - MapService, - NotificationService, - ProjectService, - RandomColorService, - StorageService, - SidenavRef, - UserService, - WaveCoreModule, -} from 'wave-core'; - -import {AppConfig} from './app-config.service'; -import {Nature40CatalogComponent} from './operators/dialogs/nature40-catalog/nature40-catalog.component'; -import {Nature40UserService} from './users/nature40-user.service'; -import {LoginComponent} from './users/login/login.component'; - -@NgModule({ - declarations: [AppComponent, LoginComponent, Nature40CatalogComponent], - imports: [ - BrowserAnimationsModule, - BrowserModule, - HttpClientModule, - RouterModule.forRoot([{path: '**', component: AppComponent}], {useHash: true}), - WaveCoreModule, - ], - providers: [ - { - provide: APP_INITIALIZER, - useFactory: (config: AppConfig) => () => config.load(), - deps: [Config], - multi: true, - }, - {provide: Config, useClass: AppConfig}, - {provide: UserService, useClass: Nature40UserService}, - LayerService, - LayoutService, - MappingQueryService, - MapService, - NotificationService, - ProjectService, - RandomColorService, - SidenavRef, - StorageService, - ], - bootstrap: [AppComponent], -}) -export class AppModule {} diff --git a/projects/nature40-app/src/app/operators/dialogs/nature40-catalog/nature40-catalog.component.html b/projects/nature40-app/src/app/operators/dialogs/nature40-catalog/nature40-catalog.component.html deleted file mode 100644 index 555ccf08..00000000 --- a/projects/nature40-app/src/app/operators/dialogs/nature40-catalog/nature40-catalog.component.html +++ /dev/null @@ -1,39 +0,0 @@ -Nature 4.0 Catalog - -
- -
-

The catalog is currently empty.

- - -

- {{ group.key }} - - open_in_new - -

- - - Raster - Vector - data_usage - - -
- -
-
-
-

- {{ entry.title }} - - open_in_new - -

-

{{ entry.description }}

-
-
- -
-
-
diff --git a/projects/nature40-app/src/app/operators/dialogs/nature40-catalog/nature40-catalog.component.scss b/projects/nature40-app/src/app/operators/dialogs/nature40-catalog/nature40-catalog.component.scss deleted file mode 100644 index 0d01060d..00000000 --- a/projects/nature40-app/src/app/operators/dialogs/nature40-catalog/nature40-catalog.component.scss +++ /dev/null @@ -1,16 +0,0 @@ -.info { - text-align: center; - - mat-spinner, - p { - margin: 2rem auto 0 auto; - } -} - -mat-list-item { - cursor: pointer; - - &:hover { - background-color: rgba(black, 0.12); - } -} diff --git a/projects/nature40-app/src/app/operators/dialogs/nature40-catalog/nature40-catalog.component.ts b/projects/nature40-app/src/app/operators/dialogs/nature40-catalog/nature40-catalog.component.ts deleted file mode 100644 index 50d53c22..00000000 --- a/projects/nature40-app/src/app/operators/dialogs/nature40-catalog/nature40-catalog.component.ts +++ /dev/null @@ -1,205 +0,0 @@ -import {ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit} from '@angular/core'; -import {HttpClient} from '@angular/common/http'; - -import {BehaviorSubject, Observable, of, throwError} from 'rxjs'; -import {first, flatMap, map} from 'rxjs/operators'; - -import {Map as ImmutableMap} from 'immutable'; - -import { - RasterSourceType, - OgrSourceType, - MappingRequestParameters, - Config, - Unit, - UnitMappingDict, - Operator, - ProjectService, - NotificationService, - RasterLayer, - MappingRasterSymbology, - DataType, - DataTypes, - ResultTypes, - Projections, - GdalSourceType, - Provenance, - UserService, -} from 'wave-core'; - -import {Nature40CatalogEntry, Nature40UserService} from '../../../users/nature40-user.service'; -import {AppConfig} from '../../../app-config.service'; - -@Component({ - selector: 'wave-nature40-catalog', - templateUrl: './nature40-catalog.component.html', - styleUrls: ['./nature40-catalog.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class Nature40CatalogComponent implements OnInit, OnDestroy { - readonly RASTER_ICON_URL: string = RasterSourceType.ICON_URL; - readonly VECTOR_ICON_URL: string = OgrSourceType.ICON_URL; - - readonly catalog$: Observable>>; - isResolving = new Map>(); - - constructor( - @Inject(Config) private readonly config: AppConfig, - @Inject(UserService) private readonly userService: Nature40UserService, - private readonly projectService: ProjectService, - private readonly notificationService: NotificationService, - private readonly http: HttpClient, - ) { - this.catalog$ = this.userService.getNature40Catalog(); - } - - ngOnInit() {} - - ngOnDestroy() { - this.isResolving.forEach((subject, _entry) => subject.complete()); - } - - isNotResolving$(entry: Nature40CatalogEntry): Observable { - if (!this.isResolving.has(entry)) { - this.isResolving.set(entry, new BehaviorSubject(false)); - } - - return this.isResolving.get(entry).pipe(map((value) => !value)); - } - - add(entry: Nature40CatalogEntry) { - if (this.isResolving.has(entry)) { - this.isResolving.get(entry).next(true); - } else { - this.isResolving.set(entry, new BehaviorSubject(true)); - } - - this.queryMetadata(entry) - .pipe( - first(), - flatMap((metadata) => { - if (!metadata) { - return throwError(`Datatype of »${entry.title}« is not yet supported`); - } - - switch (metadata.type) { - case 'gdal_source': - return of(Nature40CatalogComponent.createGdalSourceLayer(entry, metadata as GdalSourceMetadata)); - default: - return throwError(`Layer type »${metadata.type}« is not yet supported`); - } - }), - ) - .subscribe( - (layer) => { - this.isResolving.get(entry).next(false); - this.projectService.addLayer(layer); - }, - (error) => { - this.isResolving.get(entry).next(false); - this.notificationService.error(error); - }, - ); - } - - private static createGdalSourceLayer(entry: Nature40CatalogEntry, metadata: GdalSourceMetadata): RasterLayer { - for (const channel of metadata.channels) { - // TODO: smart layer for other channels - const datatype = DataTypes.fromCode(Nature40CatalogComponent.rsdbToMappingDataType(channel.datatype)); - const unit = Unit.fromMappingDict(channel.unit); - - const operator = new Operator({ - attributes: [Operator.RASTER_ATTRIBTE_NAME], - dataTypes: ImmutableMap().set(Operator.RASTER_ATTRIBTE_NAME, datatype), - operatorType: new GdalSourceType({ - channelConfig: { - displayValue: channel.name, - channelNumber: 0, - }, - sourcename: channel.file_name, - transform: false, - gdal_params: { - channels: [ - { - channel: channel.channel, - datatype: datatype.getCode(), - file_name: channel.file_name, - unit, - }, - ], - coords: { - crs: channel.crs, - }, - provenance: Nature40CatalogComponent.provenanceOfEntry(entry), - }, - }), - operatorTypeParameterOptions: undefined, - projection: Projections.fromCode(channel.crs), - resultType: ResultTypes.RASTER, - units: ImmutableMap().set(Operator.RASTER_ATTRIBTE_NAME, unit), - }); - - return new RasterLayer({ - name: entry.title, - operator, - symbology: MappingRasterSymbology.createSymbology({unit}), - }); - } - } - - private static provenanceOfEntry(entry: Nature40CatalogEntry): Provenance { - return { - citation: `${entry.title}${entry.description ? ' - ' : ''}${entry.description}`, - license: '', - uri: entry.user_url, - local_identifier: undefined, - }; - } - - private static rsdbToMappingDataType(datatype: string): string { - // TODO: migrate function to backend - return datatype.charAt(0).toUpperCase() + datatype.slice(1); - } - - private queryMetadata(entry: Nature40CatalogEntry): Observable { - const parameters = new MappingRequestParameters({ - service: 'nature40', - sessionToken: this.userService.getSession().sessionToken, - request: 'resolveCatalogEntry', - parameters: {entry: JSON.stringify(entry)}, - }); - - return this.http - .post<{result: boolean | string; metadata?: Nature40CatalogEntryMetadata}>( - this.config.MAPPING_URL, - parameters.toMessageBody(true), - {headers: parameters.getHeaders()}, - ) - .pipe( - flatMap((response) => { - if (typeof response.result === 'string') { - // error string is in the field - return throwError(response.result); - } - - return of(response.metadata); - }), - ); - } -} - -interface Nature40CatalogEntryMetadata { - type: string; -} - -interface GdalSourceMetadata extends Nature40CatalogEntryMetadata { - type: 'gdal_source'; - channels: Array<{ - crs: string; - channel: number; - datatype: string; - file_name: string; - name: string; - unit: UnitMappingDict; - }>; -} diff --git a/projects/nature40-app/src/app/users/login/login.component.html b/projects/nature40-app/src/app/users/login/login.component.html deleted file mode 100644 index a73ab511..00000000 --- a/projects/nature40-app/src/app/users/login/login.component.html +++ /dev/null @@ -1,30 +0,0 @@ - - - Login - - - - - - - User Info -
-
-

Username

-

Real Name

-

E-Mail

-
-
-

{{ (user | async).name }}

-

{{ (user | async).realName }}

-

{{ (user | async).email }}

-
-
-
- -
-
-
diff --git a/projects/nature40-app/src/app/users/login/login.component.scss b/projects/nature40-app/src/app/users/login/login.component.scss deleted file mode 100644 index 4e4c2b24..00000000 --- a/projects/nature40-app/src/app/users/login/login.component.scss +++ /dev/null @@ -1,24 +0,0 @@ -:host { - display: block; - padding: 1rem; -} - -mat-spinner { - width: 25%; - height: auto; - margin: 1rem auto; -} - -button { - margin-top: 1rem; - width: 100%; - - &.sso-button { - height: 4rem; - } -} - -.label { - color: var(--wave-foreground-secondary-text-color, grey); - margin-right: 1rem; -} diff --git a/projects/nature40-app/src/app/users/login/login.component.ts b/projects/nature40-app/src/app/users/login/login.component.ts deleted file mode 100644 index 14d1b797..00000000 --- a/projects/nature40-app/src/app/users/login/login.component.ts +++ /dev/null @@ -1,82 +0,0 @@ -import {BehaviorSubject, Observable, Subscription} from 'rxjs'; -import {first} from 'rxjs/operators'; - -import {Component, OnInit, ChangeDetectionStrategy, AfterViewInit, Inject, ChangeDetectorRef, OnDestroy} from '@angular/core'; - -import {Config, NotificationService, User, UserService} from 'wave-core'; - -import {AppConfig} from '../../app-config.service'; -import {Nature40UserService} from '../nature40-user.service'; - -enum FormStatus { - LoggedOut, - LoggedIn, - Loading, -} - -@Component({ - selector: 'wave-nature40-login', - templateUrl: './login.component.html', - styleUrls: ['./login.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LoginComponent implements OnInit, AfterViewInit, OnDestroy { - readonly FormStatus = FormStatus; - - formStatus$ = new BehaviorSubject(FormStatus.Loading); - user: Observable; - - private formStatusSubscription: Subscription; - - constructor( - @Inject(Config) private readonly config: AppConfig, - @Inject(UserService) private readonly userService: Nature40UserService, - private readonly changeDetectorRef: ChangeDetectorRef, - private readonly notificationService: NotificationService, - ) {} - - ngOnInit() { - this.userService.isSessionValid(this.userService.getSession()).subscribe((valid) => { - const isNoGuest = !this.userService.isGuestUser(); - this.formStatus$.next(valid && isNoGuest ? FormStatus.LoggedIn : FormStatus.LoggedOut); - }); - - this.user = this.userService.getUserStream(); - - this.formStatusSubscription = this.formStatus$.subscribe(() => setTimeout(() => this.changeDetectorRef.markForCheck())); - } - - ngAfterViewInit() {} - - ngOnDestroy() { - if (this.formStatusSubscription) { - this.formStatusSubscription.unsubscribe(); - } - } - - login() { - this.formStatus$.next(FormStatus.Loading); - this.userService - .getNature40JwtClientToken() - .pipe(first()) - .subscribe( - ({clientToken}: {clientToken}) => { - // no need to set form status since we redirect the page - window.location.href = this.config.NATURE40.SSO_JWT_PROVIDER_URL + clientToken; - }, - (error) => { - const errorString = error.toString() === {}.toString() ? '' : ` (${error})`; - this.notificationService.error('The backend is currently unavailable' + errorString); - this.formStatus$.next(FormStatus.LoggedOut); - }, - ); - } - - logout() { - this.formStatus$.next(FormStatus.Loading); - this.userService.guestLogin().subscribe( - () => this.formStatus$.next(FormStatus.LoggedOut), - (error) => this.notificationService.error(`The backend is currently unavailable (${error})`), - ); - } -} diff --git a/projects/nature40-app/src/app/users/nature40-user.service.ts b/projects/nature40-app/src/app/users/nature40-user.service.ts deleted file mode 100644 index 3e041c30..00000000 --- a/projects/nature40-app/src/app/users/nature40-user.service.ts +++ /dev/null @@ -1,104 +0,0 @@ -import {Inject, Injectable} from '@angular/core'; -import {HttpClient} from '@angular/common/http'; - -import {Observable, ReplaySubject} from 'rxjs'; - -import {Config, MappingRequestParameters, UserService, NotificationService} from 'wave-core'; - -import {AppConfig} from '../app-config.service'; - -@Injectable() -export class Nature40UserService extends UserService { - constructor( - @Inject(Config) protected readonly config: AppConfig, - protected readonly http: HttpClient, - protected readonly notificationService: NotificationService, - ) { - super(config, http, notificationService); - } - - /** - * Login using a JSON Web Token (JWT). - * If it was successful, set a new user. - * @param token The user's token. - * @returns `true` if the login was succesful, `false` otherwise. - */ - nature40JwtTokenLogin(token: string): Observable { - const parameters = new MappingRequestParameters({ - service: 'nature40', - sessionToken: undefined, - request: 'login', - parameters: {token}, - }); - - return this.loginRequestToUserDetails(parameters); - } - - /** - * Retrieve the signed JWT client token. - */ - getNature40JwtClientToken(): Observable<{clientToken: string}> { - const parameters = new MappingRequestParameters({ - service: 'nature40', - sessionToken: undefined, - request: 'clientToken', - parameters: {}, - }); - - return this.request<{result: string | boolean; clientToken: string}>(parameters); - } - - getNature40Catalog(): Observable>> { - const parameters = new MappingRequestParameters({ - service: 'nature40', - sessionToken: this.getSession().sessionToken, - request: 'sourcelist', - parameters: {}, - }); - - const subject = new ReplaySubject>>(1); - - this.request<{result: boolean | string; sourcelist?: Array}>(parameters).subscribe( - ({result, sourcelist}) => { - if (typeof result === 'string') { - // unsuccessful - subject.error(new Error(result)); - return; - } - - const groupedValues = new Map>(); - for (const entry of sourcelist) { - const group = entry.provider.type; - if (groupedValues.has(group)) { - groupedValues.get(group).push(entry); - } else { - groupedValues.set(group, [entry]); - } - } - - subject.next(groupedValues); - }, - () => subject.error(new Error('Unable to retrieve Nature 4.0 catalog data')), - () => subject.complete(), - ); - - return subject; - } -} - -export interface Nature40CatalogEntry { - global_id: string; - title: string; - description: string; - user_url: string; - provider: { - type: string; - id: string; - url: string; - }; - dataset: { - type: string; - id: string; - url: string; - }; -} diff --git a/projects/nature40-app/src/assets/.gitignore b/projects/nature40-app/src/assets/.gitignore deleted file mode 100644 index d344ba6b..00000000 --- a/projects/nature40-app/src/assets/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.json diff --git a/projects/nature40-app/src/assets/.gitkeep b/projects/nature40-app/src/assets/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/nature40-app/src/assets/icons/natur_40_logo.svg b/projects/nature40-app/src/assets/icons/natur_40_logo.svg deleted file mode 100644 index 0d142289..00000000 --- a/projects/nature40-app/src/assets/icons/natur_40_logo.svg +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/projects/nature40-app/src/environments/environment.prod.ts b/projects/nature40-app/src/environments/environment.prod.ts deleted file mode 100644 index da7c84f6..00000000 --- a/projects/nature40-app/src/environments/environment.prod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: true, -}; diff --git a/projects/nature40-app/src/environments/environment.ts b/projects/nature40-app/src/environments/environment.ts deleted file mode 100644 index c9cad009..00000000 --- a/projects/nature40-app/src/environments/environment.ts +++ /dev/null @@ -1,16 +0,0 @@ -// This file can be replaced during build by using the `fileReplacements` array. -// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. -// The list of file replacements can be found in `angular.json`. - -export const environment = { - production: false, -}; - -/* - * For easier debugging in development mode, you can import the following file - * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. - * - * This import should be commented out in production mode because it will have a negative impact - * on performance if an error is thrown. - */ -// import 'zone.js/dist/zone-error'; // Included with Angular CLI. diff --git a/projects/nature40-app/src/favicon.ico b/projects/nature40-app/src/favicon.ico deleted file mode 100644 index e2cef5c7..00000000 Binary files a/projects/nature40-app/src/favicon.ico and /dev/null differ diff --git a/projects/nature40-app/src/index.html b/projects/nature40-app/src/index.html deleted file mode 100644 index 5174a1f9..00000000 --- a/projects/nature40-app/src/index.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - VAT: Visualization, Analysis and Transformation System - - - - - - - -

VAT

-
- · - · - · -
-
- - diff --git a/projects/nature40-app/src/main.ts b/projects/nature40-app/src/main.ts deleted file mode 100644 index 469eddb3..00000000 --- a/projects/nature40-app/src/main.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {enableProdMode} from '@angular/core'; -import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; - -import {AppModule} from './app/app.module'; -import {environment} from './environments/environment'; - -if (environment.production) { - enableProdMode(); -} - -platformBrowserDynamic() - .bootstrapModule(AppModule) - .catch((err) => console.error(err)); diff --git a/projects/nature40-app/src/polyfills.ts b/projects/nature40-app/src/polyfills.ts deleted file mode 100644 index e49856ec..00000000 --- a/projects/nature40-app/src/polyfills.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), - * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - -/*************************************************************************************************** - * BROWSER POLYFILLS - */ - -/** IE10 and IE11 requires the following for NgClass support on SVG elements */ -// import 'classlist.js'; // Run `npm install --save classlist.js`. - -/** - * Web Animations `@angular/platform-browser/animations` - * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. - * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). - */ -// import 'web-animations-js'; // Run `npm install --save web-animations-js`. - -/** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before `zone.js` being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass `zone.js` patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - -/*************************************************************************************************** - * Zone JS is required by default for Angular itself. - */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ diff --git a/projects/nature40-app/src/styles.scss b/projects/nature40-app/src/styles.scss deleted file mode 100644 index cf2f195d..00000000 --- a/projects/nature40-app/src/styles.scss +++ /dev/null @@ -1,22 +0,0 @@ -@import 'app-theme'; - -:root { - --wave-primary-color: #{mat-color($wave-app-primary)}; - --wave-accent-color: #{mat-color($wave-app-accent)}; - --wave-warn-color: #{mat-color($wave-app-warn)}; - - --wave-faded-accent-color: #{mat-color($wave-app-accent, 0.32)}; - - --wave-foreground-text-color: #{mat-color(map-get($wave-app-theme, foreground), text)}; - --wave-foreground-secondary-text-color: #{mat-color(map-get($wave-app-theme, foreground), secondary-text)}; - - --wave-background-color: #{map-get(map-get($wave-app-theme, background), background)}; - --wave-background-hover-color: #{mat-color(map-get($wave-app-theme, background), hover)}; - - font-family: Roboto, 'Helvetica Neue', sans-serif; - font-size: 16px; -} - -a { - color: mat-color(map-get($wave-app-theme, foreground), secondary-text); -} diff --git a/projects/nature40-app/src/test.ts b/projects/nature40-app/src/test.ts deleted file mode 100644 index 7a816b2b..00000000 --- a/projects/nature40-app/src/test.ts +++ /dev/null @@ -1,23 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files - -import 'zone.js/dist/zone-testing'; -import {getTestBed} from '@angular/core/testing'; -import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing'; - -declare const require: { - context( - path: string, - deep?: boolean, - filter?: RegExp, - ): { - keys(): string[]; - (id: string): T; - }; -}; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().map(context); diff --git a/projects/nature40-app/tsconfig.app.json b/projects/nature40-app/tsconfig.app.json deleted file mode 100644 index 8212f985..00000000 --- a/projects/nature40-app/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/app", - "types": [] - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": [], - "paths": { - "wave-core": ["dist/wave-core"] - } -} diff --git a/projects/nature40-app/tsconfig.spec.json b/projects/nature40-app/tsconfig.spec.json deleted file mode 100644 index b6b4f089..00000000 --- a/projects/nature40-app/tsconfig.spec.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] -} diff --git a/projects/wave-app/.eslintrc.json b/projects/wave-app/.eslintrc.json deleted file mode 100644 index d8afd07f..00000000 --- a/projects/wave-app/.eslintrc.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": [ - "projects/wave-app/tsconfig.app.json", - "projects/wave-app/tsconfig.spec.json", - "projects/wave-app/e2e/tsconfig.json" - ], - "createDefaultProgram": true - }, - "rules": {} - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/wave-app/browserslist b/projects/wave-app/browserslist deleted file mode 100644 index 80848532..00000000 --- a/projects/wave-app/browserslist +++ /dev/null @@ -1,12 +0,0 @@ -# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. -# For additional information regarding the format and rule options, please see: -# https://github.com/browserslist/browserslist#queries - -# You can see what browsers were selected by your queries by running: -# npx browserslist - -> 0.5% -last 2 versions -Firefox ESR -not dead -not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/projects/wave-app/e2e/protractor.conf.js b/projects/wave-app/e2e/protractor.conf.js deleted file mode 100644 index bf4376ef..00000000 --- a/projects/wave-app/e2e/protractor.conf.js +++ /dev/null @@ -1,30 +0,0 @@ -// @ts-check -// Protractor configuration file, see link for more information -// https://github.com/angular/protractor/blob/master/lib/config.ts - -const {SpecReporter} = require('jasmine-spec-reporter'); - -/** - * @type { import("protractor").Config } - */ -exports.config = { - allScriptsTimeout: 11000, - specs: ['./src/**/*.e2e-spec.ts'], - capabilities: { - browserName: 'chrome', - }, - directConnect: true, - baseUrl: 'http://localhost:4200/', - framework: 'jasmine', - jasmineNodeOpts: { - showColors: true, - defaultTimeoutInterval: 30000, - print: function () {}, - }, - onPrepare() { - require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json'), - }); - jasmine.getEnv().addReporter(new SpecReporter({spec: {displayStacktrace: true}})); - }, -}; diff --git a/projects/wave-app/e2e/src/app.e2e-spec.ts b/projects/wave-app/e2e/src/app.e2e-spec.ts deleted file mode 100644 index 18d8a12b..00000000 --- a/projects/wave-app/e2e/src/app.e2e-spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {AppPage} from './app.po'; -import {browser, logging} from 'protractor'; - -describe('workspace-project App', () => { - let page: AppPage; - - beforeEach(() => { - page = new AppPage(); - }); - - it('should display welcome message', () => { - page.navigateTo(); - expect(page.getTitleText()).toEqual('wave-app app is running!'); - }); - - afterEach(async () => { - // Assert that there are no errors emitted from the browser - const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain( - jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry), - ); - }); -}); diff --git a/projects/wave-app/e2e/src/app.po.ts b/projects/wave-app/e2e/src/app.po.ts deleted file mode 100644 index c0cc0f9b..00000000 --- a/projects/wave-app/e2e/src/app.po.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {browser, by, element} from 'protractor'; - -export class AppPage { - navigateTo(): Promise { - return browser.get(browser.baseUrl) as Promise; - } - - getTitleText(): Promise { - return element(by.css('waveApp-root .content span')).getText() as Promise; - } -} diff --git a/projects/wave-app/e2e/tsconfig.json b/projects/wave-app/e2e/tsconfig.json deleted file mode 100644 index 3d39212b..00000000 --- a/projects/wave-app/e2e/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "outDir": "../../../out-tsc/e2e", - "module": "commonjs", - "target": "es5", - "types": ["jasmine", "jasminewd2", "node"] - } -} diff --git a/projects/wave-app/karma.conf.js b/projects/wave-app/karma.conf.js deleted file mode 100644 index 5c2c7c29..00000000 --- a/projects/wave-app/karma.conf.js +++ /dev/null @@ -1,32 +0,0 @@ -// Karma configuration file, see link for more information -// https://karma-runner.github.io/1.0/config/configuration-file.html - -module.exports = function (config) { - config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], - plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage-istanbul-reporter'), - require('@angular-devkit/build-angular/plugins/karma'), - ], - client: { - clearContext: false, // leave Jasmine Spec Runner output visible in browser - }, - coverageIstanbulReporter: { - dir: require('path').join(__dirname, '../../coverage/wave-app'), - reports: ['html', 'lcovonly', 'text-summary'], - fixWebpackSourcePaths: true, - }, - reporters: ['progress', 'kjhtml'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome'], - singleRun: false, - restartOnFileChange: true, - }); -}; diff --git a/projects/wave-app/src/app-theme.scss b/projects/wave-app/src/app-theme.scss deleted file mode 100644 index 91c8fbc7..00000000 --- a/projects/wave-app/src/app-theme.scss +++ /dev/null @@ -1,82 +0,0 @@ -@import '~@angular/material/theming'; - -// Material Base Styles -@include mat-core(); - -// Define Colors -$gfbio-darkblue: ( - 50: #e7ebf4, - 100: #c2cee3, - 200: #99add1, - 300: #708cbf, - 400: #5273b1, - 500: #335aa3, - 600: #2e529b, - 700: #274891, - 800: #203f88, - 900: #142e77, - A100: #adc0ff, - A200: #7a98ff, - A400: #4770ff, - A700: #2e5dff, - contrast: ( - 50: $black-87-opacity, - 100: $black-87-opacity, - 200: $black-87-opacity, - 300: $black-87-opacity, - 400: $white-87-opacity, - 500: $white-87-opacity, - 600: $white-87-opacity, - 700: $white-87-opacity, - 800: $white-87-opacity, - 900: $white-87-opacity, - A100: $black-87-opacity, - A200: $black-87-opacity, - A400: $white-87-opacity, - A700: $white-87-opacity, - ), -); - -$gfbio-green: ( - 50: #f0f6e9, - 100: #d9e8c8, - 200: #c0d9a4, - 300: #a7c97f, - 400: #94be63, - 500: #81b248, - 600: #79ab41, - 700: #6ea238, - 800: #649930, - 900: #518a21, - A100: #dfffc7, - A200: #c2ff94, - A400: #a5ff61, - A700: #97ff47, - contrast: ( - 50: $black-87-opacity, - 100: $black-87-opacity, - 200: $black-87-opacity, - 300: $black-87-opacity, - 400: $black-87-opacity, - 500: $black-87-opacity, - 600: $black-87-opacity, - 700: $black-87-opacity, - 800: $white-87-opacity, - 900: $white-87-opacity, - A100: $black-87-opacity, - A200: $black-87-opacity, - A400: $black-87-opacity, - A700: $black-87-opacity, - ), -); - -// Define App Theme -$wave-app-primary: mat-palette($gfbio-darkblue); -$wave-app-accent: mat-palette($gfbio-green, A200, A100, A400); -$wave-app-warn: mat-palette($mat-red); - -// Create the theme object (a Sass map containing all of the palettes). -$wave-app-theme: mat-light-theme($wave-app-primary, $wave-app-accent, $wave-app-warn); - -// Apply Angular Material Mixin to Color Theme -@include angular-material-theme($wave-app-theme); diff --git a/projects/wave-app/src/app/app-config.service.ts b/projects/wave-app/src/app/app-config.service.ts deleted file mode 100644 index 8b4a97db..00000000 --- a/projects/wave-app/src/app/app-config.service.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {Injectable} from '@angular/core'; -import {mergeDeep} from 'immutable'; -import {Config, WaveConfigStructure, WAVE_DEFAULT_CONFIG} from 'wave-core'; - -interface Components { - readonly PLAYBACK: { - readonly AVAILABLE: boolean; - }; -} - -interface AppConfigStructure extends WaveConfigStructure { - readonly COMPONENTS: Components; -} - -const APP_CONFIG_DEFAULTS = mergeDeep(WAVE_DEFAULT_CONFIG, { - COMPONENTS: { - PLAYBACK: { - AVAILABLE: false, - }, - }, -}) as AppConfigStructure; - -@Injectable() -export class AppConfig extends Config { - protected config: AppConfigStructure; - - get COMPONENTS(): Components { - return this.config.COMPONENTS; - } - - load(): Promise { - return super.load(APP_CONFIG_DEFAULTS); - } -} diff --git a/projects/wave-app/src/app/app.component.html b/projects/wave-app/src/app/app.component.html deleted file mode 100644 index c40008c9..00000000 --- a/projects/wave-app/src/app/app.component.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - -
- - - -
- -
- - - - - -
- - - - - - - - - - - - - - - - -
-
- - - - -
Data Table
-
- - -
- - -
Citations
-
- - -
-
-
-
diff --git a/projects/wave-app/src/app/app.component.scss b/projects/wave-app/src/app/app.component.scss deleted file mode 100644 index 6fd8fae1..00000000 --- a/projects/wave-app/src/app/app.component.scss +++ /dev/null @@ -1,115 +0,0 @@ -wave-navigation { - z-index: 10; -} - -wave-layer-list { - position: absolute; - z-index: 2; - width: 16vw; - min-width: 200px; - left: 0; - top: 0; - background-color: rgba(255, 255, 255, 0.87); - border-bottom-right-radius: 2px; -} - -.time-container { - position: absolute; - left: 16vw; - right: 16vw; - - wave-ticker-interaction, - wave-small-time-interaction, - wave-zoom-handles { - background-color: rgba(255, 255, 255, 0.87); - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; - z-index: 3; - } -} - -:host ::ng-deep .mat-sidenav-content { - overflow: hidden; -} - -.top-container { - z-index: 1; -} - -.mid-container { - z-index: 0; - position: relative; -} - -.bottom-container { - position: relative; - z-index: 1; - - min-height: 3rem; - @media (max-width: 600px) and (orientation: portrait) { - min-height: 2.5rem; - } - @media (max-width: 960px) and (orientation: landscape) { - min-height: 2rem; - } - - .toggle { - position: absolute; - z-index: 1; - padding: 0; - min-width: 3rem; - width: 3rem; - height: 3rem; - @media (max-width: 600px) and (orientation: portrait) { - min-width: 2.5rem; - width: 2.5rem; - height: 2.5rem; - } - @media (max-width: 960px) and (orientation: landscape) { - min-width: 2rem; - width: 2rem; - height: 2rem; - } - } - - ::ng-deep .mat-tab-label-container { - margin-left: 3rem; - @media (max-width: 600px) and (orientation: portrait) { - margin-left: 2.5rem; - } - @media (max-width: 960px) and (orientation: landscape) { - margin-left: 2rem; - } - } - - @media (max-width: 960px) and (orientation: landscape) { - ::ng-deep mat-tab-header { - height: 2rem; - } - ::ng-deep .mat-tab-label { - line-height: 2rem; - } - } - @media (max-width: 600px) and (orientation: portrait) { - ::ng-deep mat-tab-header { - height: 2.5rem; - } - ::ng-deep .mat-tab-label { - line-height: 2.5rem; - } - } -} - -.bottom-container.small { - max-height: 3rem !important; - @media (max-width: 600px) and (orientation: portrait) { - max-height: 2.5rem !important; - } - @media (max-width: 960px) and (orientation: landscape) { - max-height: 2rem !important; - } - - ::ng-deep mat-tab-header { - border: 0; - } -} diff --git a/projects/wave-app/src/app/app.component.ts b/projects/wave-app/src/app/app.component.ts deleted file mode 100644 index 168bc9dc..00000000 --- a/projects/wave-app/src/app/app.component.ts +++ /dev/null @@ -1,275 +0,0 @@ -import {Observable, BehaviorSubject} from 'rxjs'; -import {map, tap, first} from 'rxjs/operators'; - -import { - AfterViewInit, - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - HostListener, - Inject, - OnInit, - ViewChild, - ViewContainerRef, -} from '@angular/core'; -import {MatDialog} from '@angular/material/dialog'; -import {MatIconRegistry} from '@angular/material/icon'; -import {MatSidenav} from '@angular/material/sidenav'; -import {MatTabGroup} from '@angular/material/tabs'; -import { - Layer, - SidenavContainerComponent, - MapContainerComponent, - AbstractSymbology, - LayerService, - LayoutService, - ProjectService, - UserService, - StorageService, - RandomColorService, - MappingQueryService, - NotificationService, - MapService, - Config, - ResultTypes, - PointSymbology, - VectorSymbology, - LineSymbology, - PlotListComponent, - WorkflowParameterChoiceDialogComponent, - NavigationButton, - SourceOperatorListComponent, - NavigationComponent, - OperatorListComponent, - TimeConfigComponent, - WorkspaceSettingsComponent, - HelpComponent, - SourceOperatorListButton, - GFBioSourceType, - GbifOperatorComponent, - OperatorListButtonGroups, - SidenavConfig, -} from 'wave-core'; -import {DomSanitizer} from '@angular/platform-browser'; -import {ActivatedRoute} from '@angular/router'; -import {AppConfig} from './app-config.service'; - -@Component({ - selector: 'wave-app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AppComponent implements OnInit, AfterViewInit { - @ViewChild(MapContainerComponent, {static: true}) mapComponent: MapContainerComponent; - @ViewChild(MatTabGroup, {static: true}) bottomTabs: MatTabGroup; - - @ViewChild(MatSidenav, {static: true}) rightSidenav: MatSidenav; - @ViewChild(SidenavContainerComponent, {static: true}) rightSidenavContainer: SidenavContainerComponent; - - readonly ResultTypes = ResultTypes; - readonly LayoutService = LayoutService; - - readonly layersReverse$: Observable>>; - readonly layerListVisible$: Observable; - readonly layerDetailViewVisible$: Observable; - - readonly navigationButtons = this.setupNavigation(); - readonly addAFirstLayerConfig = AppComponent.setupAddDataConfig(); - - middleContainerHeight$: Observable; - bottomContainerHeight$: Observable; - mapIsGrid$: Observable; - - private windowHeight$ = new BehaviorSubject(window.innerHeight); - - constructor( - @Inject(Config) readonly config: AppConfig, - readonly layerService: LayerService, - readonly layoutService: LayoutService, - readonly projectService: ProjectService, - readonly vcRef: ViewContainerRef, // reference used by color picker - private userService: UserService, - private storageService: StorageService, - private changeDetectorRef: ChangeDetectorRef, - private dialog: MatDialog, - private iconRegistry: MatIconRegistry, - private randomColorService: RandomColorService, - private mappingQueryService: MappingQueryService, - private activatedRoute: ActivatedRoute, - private notificationService: NotificationService, - private mapService: MapService, - private sanitizer: DomSanitizer, - ) { - this.registerIcons(); - - vcRef.length; // eslint-disable-line @typescript-eslint/no-unused-expressions - - this.storageService.toString(); // just register - - this.layersReverse$ = this.projectService.getLayerStream().pipe(map((layers) => layers.slice(0).reverse())); - - this.layerListVisible$ = this.layoutService.getLayerListVisibilityStream(); - this.layerDetailViewVisible$ = this.layoutService.getLayerDetailViewVisibilityStream(); - } - - private registerIcons() { - this.iconRegistry.addSvgIconInNamespace('vat', 'logo', this.sanitizer.bypassSecurityTrustResourceUrl('assets/vat_logo.svg')); - - // used for navigation - this.iconRegistry.addSvgIcon('cogs', this.sanitizer.bypassSecurityTrustResourceUrl('assets/icons/cogs.svg')); - - // TODO: migrate to geo bon app - // this.iconRegistry.addSvgIconInNamespace( - // 'geobon', - // 'logo', - // this.sanitizer.bypassSecurityTrustResourceUrl('assets/geobon-logo.svg'), - // ); - } - - ngOnInit() { - this.mapService.registerMapComponent(this.mapComponent); - this.mapIsGrid$ = this.mapService.isGrid$; - - this.middleContainerHeight$ = this.layoutService.getMapHeightStream(this.windowHeight$).pipe(tap(() => this.mapComponent.resize())); - this.bottomContainerHeight$ = this.layoutService.getLayerDetailViewStream(this.windowHeight$); - } - - ngAfterViewInit() { - this.layoutService.getSidenavContentComponentStream().subscribe((sidenavConfig) => { - this.rightSidenavContainer.load(sidenavConfig); - if (sidenavConfig) { - this.rightSidenav.open(); - } else { - this.rightSidenav.close(); - } - }); - this.projectService - .getNewPlotStream() - .subscribe(() => this.layoutService.setSidenavContentComponent({component: PlotListComponent})); - - // set the stored tab index - this.layoutService.getLayerDetailViewTabIndexStream().subscribe((tabIndex) => { - if (this.bottomTabs.selectedIndex !== tabIndex) { - this.bottomTabs.selectedIndex = tabIndex; - setTimeout(() => this.changeDetectorRef.markForCheck()); - } - }); - - this.handleQueryParameters(); - } - - setTabIndex(index: number) { - this.layoutService.setLayerDetailViewTabIndex(index); - this.layoutService.setLayerDetailViewVisibility(true); - } - - private setupNavigation(): Array { - return [ - NavigationComponent.createLoginButton(this.userService, this.layoutService, this.config), - { - sidenavConfig: AppComponent.setupAddDataConfig(), - icon: 'add', - tooltip: 'Add Data', - }, - { - sidenavConfig: {component: OperatorListComponent, config: {operators: AppComponent.createOperatorListButtons()}}, - icon: '', - svgIcon: 'cogs', - tooltip: 'Operators', - }, - { - sidenavConfig: {component: PlotListComponent}, - icon: 'equalizer', - tooltip: 'Plots', - }, - { - sidenavConfig: {component: TimeConfigComponent}, - icon: 'access_time', - tooltip: 'Time', - }, - { - sidenavConfig: {component: WorkspaceSettingsComponent}, - icon: 'settings', - tooltip: 'Workspace', - }, - { - sidenavConfig: {component: HelpComponent}, - icon: 'help', - tooltip: 'Help', - }, - ]; - } - - private static setupAddDataConfig(): SidenavConfig { - return {component: SourceOperatorListComponent, config: {buttons: AppComponent.createSourceOperatorListButtons()}}; - } - - private static createSourceOperatorListButtons(): Array { - return [ - SourceOperatorListComponent.createDataRepositoryButton(), - SourceOperatorListComponent.createDrawFeaturesButton(), - ...SourceOperatorListComponent.createCustomFeaturesButtons(), - { - name: 'Species Occurrences', - description: 'Query data from GBIF', - iconSrc: GFBioSourceType.ICON_URL, - sidenavConfig: {component: GbifOperatorComponent, keepParent: true}, - }, - SourceOperatorListComponent.createCountryPolygonsButton(), - ]; - } - - private static createOperatorListButtons(): OperatorListButtonGroups { - return [ - {name: 'Mixed', list: OperatorListComponent.DEFAULT_MIXED_OPERATOR_DIALOGS}, - {name: 'Plots', list: OperatorListComponent.DEFAULT_PLOT_OPERATOR_DIALOGS}, - {name: 'Raster', list: OperatorListComponent.DEFAULT_RASTER_OPERATOR_DIALOGS}, - {name: 'Vector', list: OperatorListComponent.DEFAULT_VECTOR_OPERATOR_DIALOGS}, - ]; - } - - @HostListener('window:resize') - private windowHeight() { - this.windowHeight$.next(window.innerHeight); - } - - private handleQueryParameters() { - this.activatedRoute.queryParams.subscribe((p) => { - for (const parameter of Object.keys(p)) { - const value = p[parameter]; - switch (parameter) { - case 'workflow': - try { - const newLayer = Layer.fromDict(JSON.parse(value)); - this.projectService - .getProjectStream() - .pipe(first()) - .subscribe((project) => { - if (project.layers.length > 0) { - // show popup - this.dialog.open(WorkflowParameterChoiceDialogComponent, { - data: { - dialogTitle: 'Workflow URL Parameter', - sourceName: 'URL parameter', - layers: [newLayer], - nonAvailableNames: [], - numberOfLayersInProject: project.layers.length, - }, - }); - } else { - // just add the layer if the layer array is empty - this.projectService.addLayer(newLayer); - } - }); - } catch (error) { - this.notificationService.error(`Invalid Workflow: »${error}«`); - } - break; - default: - this.notificationService.error(`Unknown URL Parameter »${parameter}«`); - } - } - }); - } -} diff --git a/projects/wave-app/src/app/app.module.ts b/projects/wave-app/src/app/app.module.ts deleted file mode 100644 index 7448c83e..00000000 --- a/projects/wave-app/src/app/app.module.ts +++ /dev/null @@ -1,54 +0,0 @@ -import {APP_INITIALIZER, NgModule} from '@angular/core'; -import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; -import {BrowserModule} from '@angular/platform-browser'; -import {HttpClientModule} from '@angular/common/http'; -import {RouterModule} from '@angular/router'; - -import {AppComponent} from './app.component'; -import { - Config, - LayerService, - LayoutService, - MappingQueryService, - MapService, - NotificationService, - ProjectService, - RandomColorService, - StorageService, - SidenavRef, - UserService, - WaveCoreModule, -} from 'wave-core'; -import {AppConfig} from './app-config.service'; - -@NgModule({ - declarations: [AppComponent], - imports: [ - BrowserAnimationsModule, - BrowserModule, - HttpClientModule, - RouterModule.forRoot([{path: '**', component: AppComponent}], {useHash: true}), - WaveCoreModule, - ], - providers: [ - {provide: Config, useClass: AppConfig}, - { - provide: APP_INITIALIZER, - useFactory: (config: AppConfig) => () => config.load(), - deps: [Config], - multi: true, - }, - LayerService, - LayoutService, - MappingQueryService, - MapService, - NotificationService, - ProjectService, - RandomColorService, - SidenavRef, - StorageService, - UserService, - ], - bootstrap: [AppComponent], -}) -export class AppModule {} diff --git a/projects/wave-app/src/assets/.gitignore b/projects/wave-app/src/assets/.gitignore deleted file mode 100644 index d344ba6b..00000000 --- a/projects/wave-app/src/assets/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.json diff --git a/projects/wave-app/src/assets/.gitkeep b/projects/wave-app/src/assets/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-app/src/environments/environment.prod.ts b/projects/wave-app/src/environments/environment.prod.ts deleted file mode 100644 index da7c84f6..00000000 --- a/projects/wave-app/src/environments/environment.prod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: true, -}; diff --git a/projects/wave-app/src/environments/environment.ts b/projects/wave-app/src/environments/environment.ts deleted file mode 100644 index c9cad009..00000000 --- a/projects/wave-app/src/environments/environment.ts +++ /dev/null @@ -1,16 +0,0 @@ -// This file can be replaced during build by using the `fileReplacements` array. -// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. -// The list of file replacements can be found in `angular.json`. - -export const environment = { - production: false, -}; - -/* - * For easier debugging in development mode, you can import the following file - * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. - * - * This import should be commented out in production mode because it will have a negative impact - * on performance if an error is thrown. - */ -// import 'zone.js/dist/zone-error'; // Included with Angular CLI. diff --git a/projects/wave-app/src/favicon.ico b/projects/wave-app/src/favicon.ico deleted file mode 100644 index e2cef5c7..00000000 Binary files a/projects/wave-app/src/favicon.ico and /dev/null differ diff --git a/projects/wave-app/src/index.html b/projects/wave-app/src/index.html deleted file mode 100644 index 238e3d14..00000000 --- a/projects/wave-app/src/index.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - VAT: Visualization, Analysis and Transformation System - - - - - - - -

VAT

-
- · - · - · -
-
- - diff --git a/projects/wave-app/src/main.ts b/projects/wave-app/src/main.ts deleted file mode 100644 index 469eddb3..00000000 --- a/projects/wave-app/src/main.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {enableProdMode} from '@angular/core'; -import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; - -import {AppModule} from './app/app.module'; -import {environment} from './environments/environment'; - -if (environment.production) { - enableProdMode(); -} - -platformBrowserDynamic() - .bootstrapModule(AppModule) - .catch((err) => console.error(err)); diff --git a/projects/wave-app/src/polyfills.ts b/projects/wave-app/src/polyfills.ts deleted file mode 100644 index e49856ec..00000000 --- a/projects/wave-app/src/polyfills.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), - * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - -/*************************************************************************************************** - * BROWSER POLYFILLS - */ - -/** IE10 and IE11 requires the following for NgClass support on SVG elements */ -// import 'classlist.js'; // Run `npm install --save classlist.js`. - -/** - * Web Animations `@angular/platform-browser/animations` - * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. - * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). - */ -// import 'web-animations-js'; // Run `npm install --save web-animations-js`. - -/** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before `zone.js` being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass `zone.js` patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - -/*************************************************************************************************** - * Zone JS is required by default for Angular itself. - */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ diff --git a/projects/wave-app/src/styles.scss b/projects/wave-app/src/styles.scss deleted file mode 100644 index cf2f195d..00000000 --- a/projects/wave-app/src/styles.scss +++ /dev/null @@ -1,22 +0,0 @@ -@import 'app-theme'; - -:root { - --wave-primary-color: #{mat-color($wave-app-primary)}; - --wave-accent-color: #{mat-color($wave-app-accent)}; - --wave-warn-color: #{mat-color($wave-app-warn)}; - - --wave-faded-accent-color: #{mat-color($wave-app-accent, 0.32)}; - - --wave-foreground-text-color: #{mat-color(map-get($wave-app-theme, foreground), text)}; - --wave-foreground-secondary-text-color: #{mat-color(map-get($wave-app-theme, foreground), secondary-text)}; - - --wave-background-color: #{map-get(map-get($wave-app-theme, background), background)}; - --wave-background-hover-color: #{mat-color(map-get($wave-app-theme, background), hover)}; - - font-family: Roboto, 'Helvetica Neue', sans-serif; - font-size: 16px; -} - -a { - color: mat-color(map-get($wave-app-theme, foreground), secondary-text); -} diff --git a/projects/wave-app/src/test.ts b/projects/wave-app/src/test.ts deleted file mode 100644 index 7a816b2b..00000000 --- a/projects/wave-app/src/test.ts +++ /dev/null @@ -1,23 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files - -import 'zone.js/dist/zone-testing'; -import {getTestBed} from '@angular/core/testing'; -import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing'; - -declare const require: { - context( - path: string, - deep?: boolean, - filter?: RegExp, - ): { - keys(): string[]; - (id: string): T; - }; -}; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().map(context); diff --git a/projects/wave-app/tsconfig.app.json b/projects/wave-app/tsconfig.app.json deleted file mode 100644 index 8212f985..00000000 --- a/projects/wave-app/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/app", - "types": [] - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": [], - "paths": { - "wave-core": ["dist/wave-core"] - } -} diff --git a/projects/wave-app/tsconfig.spec.json b/projects/wave-app/tsconfig.spec.json deleted file mode 100644 index b6b4f089..00000000 --- a/projects/wave-app/tsconfig.spec.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] -} diff --git a/projects/wave-core-new/package.json b/projects/wave-core-new/package.json index afb78a52..d48bacf3 100644 --- a/projects/wave-core-new/package.json +++ b/projects/wave-core-new/package.json @@ -9,23 +9,33 @@ "registry": "https://npm.pkg.github.com/" }, "peerDependencies": { - "@angular/cdk": "~10.2.4", - "@angular/common": "^10.1.5", - "@angular/core": "^10.1.5", - "@angular/forms": "~10.1.5", - "@angular/material": "~10.2.4", + "@angular/animations": "~11.2.7", + "@angular/cdk": "~11.2.6", + "@angular/common": "~11.2.7", + "@angular/compiler": "~11.2.7", + "@angular/core": "~11.2.7", + "@angular/flex-layout": "~11.0.0-beta.33", + "@angular/forms": "~11.2.7", + "@angular/material": "~11.2.6", + "@angular/platform-browser": "~11.2.7", + "@angular/platform-browser-dynamic": "~11.2.7", + "@angular/router": "~11.2.7", "codemirror": "~5.58.1", - "d3": "~5.16.0", + "d3": "~6.2.0", "dagre": "~0.8.5", "dagre-d3": "~0.6.4", + "hellojs": "~1.18.6", + "html2canvas": "~1.0.0-rc.5", "immutable": "~4.0.0-rc.12", "moment": "~2.29.1", - "ngx-color-picker": "~9.0.0", + "ngx-color-picker": "~10.1.0", "ol": "~6.4.3", "papaparse": "~5.3.0", "proj4": "~2.6.2", + "rxjs": "~6.6.3", "vega": "~5.19.1", "vega-embed": "~6.15.1", - "vega-lite": "~4.17.0" + "vega-lite": "~4.17.0", + "zone.js": "~0.10.3" } } diff --git a/projects/wave-core-new/src/lib/backend/backend.model.ts b/projects/wave-core-new/src/lib/backend/backend.model.ts index f9655aa2..882b0ba2 100644 --- a/projects/wave-core-new/src/lib/backend/backend.model.ts +++ b/projects/wave-core-new/src/lib/backend/backend.model.ts @@ -249,6 +249,10 @@ export interface DataSetDict { source_operator: string; } +export interface DataSetIdDict { + Internal?: InternalDataSetIdDict; +} + export interface InternalDataSetIdDict { Internal: UUID; } @@ -298,3 +302,11 @@ export interface MeasurementDict { }; }; } + +export interface UploadResponseDict { + id: UUID; +} + +export interface CreateDataSetDict { + upload: UUID; +} diff --git a/projects/wave-core-new/src/lib/backend/backend.service.ts b/projects/wave-core-new/src/lib/backend/backend.service.ts index 16e13d91..81946658 100644 --- a/projects/wave-core-new/src/lib/backend/backend.service.ts +++ b/projects/wave-core-new/src/lib/backend/backend.service.ts @@ -1,5 +1,5 @@ import {Injectable} from '@angular/core'; -import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; +import {HttpClient, HttpEvent, HttpHeaders, HttpParams} from '@angular/common/http'; import {Observable, Subject} from 'rxjs'; import {Config} from '../config.service'; import {bboxDictToExtent, unixTimestampToIsoString} from '../util/conversions'; @@ -27,6 +27,9 @@ import { RasterResultDescriptorDict, PlotResultDescriptorDict, VectorResultDescriptorDict, + UploadResponseDict, + DataSetIdDict, + CreateDataSetDict, } from './backend.model'; @Injectable({ @@ -241,6 +244,20 @@ export class BackendService { }); } + upload(sessionId: UUID, form: FormData): Observable> { + return this.http.post(this.config.API_URL + '/upload', form, { + headers: BackendService.authorizationHeader(sessionId), + reportProgress: true, + observe: 'events', + }); + } + + createDataSet(sessionId: UUID, createDataSet: CreateDataSetDict): Observable { + return this.http.post(this.config.API_URL + '/dataset', createDataSet, { + headers: BackendService.authorizationHeader(sessionId), + }); + } + private static authorizationHeader(sessionId: UUID): HttpHeaders { return new HttpHeaders().set('Authorization', `Bearer ${sessionId}`); } diff --git a/projects/wave-core-new/src/lib/datasets/add-data/add-data.component.ts b/projects/wave-core-new/src/lib/datasets/add-data/add-data.component.ts index acf6e42e..d47d3f77 100644 --- a/projects/wave-core-new/src/lib/datasets/add-data/add-data.component.ts +++ b/projects/wave-core-new/src/lib/datasets/add-data/add-data.component.ts @@ -1,8 +1,10 @@ import {Component, OnInit, ChangeDetectionStrategy, Input} from '@angular/core'; import {LayoutService, SidenavConfig} from '../../layout.service'; +import {createIconDataUrl} from '../../util/icons'; import {DatasetListComponent} from '../dataset-list/dataset-list.component'; +import {UploadComponent} from '../upload/upload.component'; -export interface AddDataListButton { +export interface AddDataButton { name: string; description: string; icon?: string; @@ -21,7 +23,7 @@ export class AddDataComponent implements OnInit { /** * A list of data source dialogs to display */ - @Input() buttons!: Array; + @Input() buttons!: Array; constructor(private layoutService: LayoutService) {} @@ -38,47 +40,21 @@ export class AddDataComponent implements OnInit { this.layoutService.setSidenavContentComponent(sidenavConfig); } - static createDataSetListButton(): AddDataListButton { + static createDataSetListButton(): AddDataButton { return { name: 'Data Sets', description: 'Available Data Sets', - iconSrc: this.createIconDataUrl('DataSets'), + iconSrc: createIconDataUrl('DataSets'), sidenavConfig: {component: DatasetListComponent, keepParent: true}, }; } - /** - * Each operator type must have a method that returns - * an icon as a data uri image. This provides a default - * out of the operator name. - */ - static createIconDataUrl(iconName: string): string { - // TODO: replace with proper icons - // from `http://stackoverflow.com/questions/3426404/ - // create-a-hexadecimal-colour-based-on-a-string-with-javascript` - const hashCode = (str: string): number => { - // java String#hashCode - let hash = 0; - for (let i = 0; i < str.length; i++) { - hash = str.charCodeAt(i) + ((hash << 5) - hash); // eslint-disable-line no-bitwise - } - return hash; - }; - const intToRGB = (i: number): string => { - const c = (i & 0x00ffffff).toString(16).toUpperCase(); // eslint-disable-line no-bitwise - - return '00000'.substring(0, 6 - c.length) + c; + static createUploadButton(): AddDataButton { + return { + name: 'Upload', + description: 'Upload data from you local computer', + iconSrc: createIconDataUrl('Upload'), + sidenavConfig: {component: UploadComponent, keepParent: true}, }; - - const color = '#' + intToRGB(hashCode(iconName)); - const size = 64; - - const canvas = document.createElement('canvas'); - canvas.width = size; - canvas.height = size; - const context = canvas.getContext('2d'); - context.fillStyle = color; - context.fillRect(0, 0, 64, 64); - return canvas.toDataURL('image/png'); } } diff --git a/projects/wave-core-new/src/lib/datasets/dataset.service.ts b/projects/wave-core-new/src/lib/datasets/dataset.service.ts index f57396aa..d177ea44 100644 --- a/projects/wave-core-new/src/lib/datasets/dataset.service.ts +++ b/projects/wave-core-new/src/lib/datasets/dataset.service.ts @@ -4,6 +4,8 @@ import {Observable} from 'rxjs'; import {DataSet} from './dataset.model'; import {UserService} from '../users/user.service'; import {map, mergeMap} from 'rxjs/operators'; +import {HttpEvent} from '@angular/common/http'; +import {CreateDataSetDict, DataSetIdDict, UploadResponseDict} from '../backend/backend.model'; @Injectable({ providedIn: 'root', @@ -17,4 +19,12 @@ export class DataSetService { map((dataSetDicts) => dataSetDicts.map((dict) => DataSet.fromDict(dict))), ); } + + upload(form: FormData): Observable> { + return this.userService.getSessionTokenForRequest().pipe(mergeMap((token) => this.backend.upload(token, form))); + } + + createDataSet(create: CreateDataSetDict): Observable { + return this.userService.getSessionTokenForRequest().pipe(mergeMap((token) => this.backend.createDataSet(token, create))); + } } diff --git a/projects/wave-core-new/src/lib/datasets/upload/upload.component.html b/projects/wave-core-new/src/lib/datasets/upload/upload.component.html new file mode 100644 index 00000000..9e038e1b --- /dev/null +++ b/projects/wave-core-new/src/lib/datasets/upload/upload.component.html @@ -0,0 +1,66 @@ +Add Data + + + + Select files for upload + + + + +
+ +
+ +
+
+ + + + Specify loading information + + + +

Upload ID: {{ uploadId }}

+ +
Specify the loading info as Json
+ +
+ + Choose an example + + + {{ option.name }} + + + +
+
+ +
+
+ +
+
+
+ + + + Upload succesful! + + + Dataset ID: {{ dataSetId.id.Internal }} + + + diff --git a/projects/wave-core-new/src/lib/datasets/upload/upload.component.scss b/projects/wave-core-new/src/lib/datasets/upload/upload.component.scss new file mode 100644 index 00000000..b80d6a39 --- /dev/null +++ b/projects/wave-core-new/src/lib/datasets/upload/upload.component.scss @@ -0,0 +1,22 @@ +:host { + display: block; + padding: 1rem; +} + +.actions { + padding: 1rem; +} + +mat-card { + margin-bottom: 1rem; +} + +mat-spinner { + width: 25%; + height: auto; + margin: 1rem auto; +} + +textarea { + width: 100%; +} diff --git a/projects/wave-core-new/src/lib/datasets/upload/upload.component.ts b/projects/wave-core-new/src/lib/datasets/upload/upload.component.ts new file mode 100644 index 00000000..d75d2f78 --- /dev/null +++ b/projects/wave-core-new/src/lib/datasets/upload/upload.component.ts @@ -0,0 +1,194 @@ +import {HttpEventType} from '@angular/common/http'; +import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; +import {Subject} from 'rxjs'; +import {DataSetIdDict, UUID} from '../../backend/backend.model'; +import {NotificationService} from '../../notification.service'; +import {DataSetService} from '../dataset.service'; + +interface ExampleLoadingInfo { + name: string; + json: string; +} + +@Component({ + selector: 'wave-upload', + templateUrl: './upload.component.html', + styleUrls: ['./upload.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class UploadComponent implements OnInit { + selectedFiles: FileList; + progress$ = new Subject(); + indicateLoading$ = new Subject(); + submittedUpload = false; + submittedCreate = false; + + uploadId$: Subject = new Subject(); + + dataSetId$: Subject = new Subject(); + + exampleLoadingInfos: Array = [ + { + name: 'NDVI', + json: `{ + "properties": { + "id": null, + "name": "Uploaded NDVI", + "description": "NDVI data from MODIS", + "source_operator": "GdalSource" + }, + "meta_data": { + "GdalMetaDataRegular": { + "result_descriptor": { + "data_type": "U8", + "spatial_reference": "EPSG:4326", + "measurement": "unitless" + }, + "params": { + "file_path": "operators/test-data/raster/modis_ndvi/MOD13A2_M_NDVI_%%%_START_TIME_%%%.TIFF", + "rasterband_channel": 1, + "geo_transform": { + "origin_coordinate": { + "x": -180.0, + "y": 90.0 + }, + "x_pixel_size": 0.1, + "y_pixel_size": -0.1 + }, + "bbox": { + "lower_left_coordinate": { + "x": -180.0, + "y": -90.0 + }, + "upper_right_coordinate": { + "x": 180.0, + "y": 90.0 + } + }, + "file_not_found_handling": "NoData" + }, + "placeholder": "%%%_START_TIME_%%%", + "time_format": "%Y-%m-%d", + "start": 1388534400000, + "step": { + "granularity": "Months", + "step": 1 + } + } + } + }`, + }, + { + name: 'Ports', + json: `{ + "properties": { + "id": null, + "name": "Uploaded Natural Earth 10m Ports", + "description": "Ports from Natural Earth", + "source_operator": "OgrSource" + }, + "meta_data": { + "OgrMetaData": { + "loading_info": { + "file_name": "operators/test-data/vector/data/ne_10m_ports/ne_10m_ports.shp", + "layer_name": "ne_10m_ports", + "data_type": "MultiPoint", + "time": "none", + "columns": { + "x": "", + "y": null, + "numeric": [ + "natlscale" + ], + "decimal": [ + "scalerank" + ], + "textual": [ + "featurecla", + "name", + "website" + ] + }, + "default_geometry": null, + "force_ogr_time_filter": false, + "on_error": "skip", + "provenance": null + }, + "result_descriptor": { + "data_type": "MultiPoint", + "spatial_reference": "EPSG:4326", + "columns": { + "website": "Text", + "name": "Text", + "natlscale": "Number", + "scalerank": "Decimal", + "featurecla": "Text" + } + } + } + } + }`, + }, + ]; + + loadingInfo = ''; + + constructor(protected dataSetService: DataSetService, protected notificationService: NotificationService) {} + + ngOnInit(): void {} + + selectFiles(event): void { + this.selectedFiles = event.target.files; + } + + upload(): void { + const form = new FormData(); + + for (const file of Array.from(this.selectedFiles)) { + form.append('files[]', file, file.name); + } + + this.submittedUpload = true; + this.indicateLoading$.next(true); + + this.dataSetService.upload(form).subscribe( + (event) => { + if (event.type === HttpEventType.UploadProgress) { + this.progress$.next(Math.round((100 * event.loaded) / event.total)); + } else if (event.type === HttpEventType.Response) { + this.uploadId$.next(event.body.id); + this.indicateLoading$.next(false); + } + }, + (err) => { + this.notificationService.error('File upload failed: ' + err); + this.indicateLoading$.next(false); + }, + ); + } + + selectLoadingInfo(info: ExampleLoadingInfo): void { + this.loadingInfo = info.json; + } + + submitLoadingInfo(uploadId: UUID): void { + this.submittedCreate = true; + this.indicateLoading$.next(true); + + const create = { + upload: uploadId, + definition: JSON.parse(this.loadingInfo), + }; + + this.dataSetService.createDataSet(create).subscribe( + (id) => { + this.dataSetId$.next(id); + this.indicateLoading$.next(false); + }, + (err) => { + this.notificationService.error('Create dataset failed: ' + err); + this.indicateLoading$.next(false); + }, + ); + } +} diff --git a/projects/wave-core-new/src/lib/project/project.service.ts b/projects/wave-core-new/src/lib/project/project.service.ts index 0593750f..6e77a4ef 100644 --- a/projects/wave-core-new/src/lib/project/project.service.ts +++ b/projects/wave-core-new/src/lib/project/project.service.ts @@ -791,7 +791,7 @@ export class ProjectService { protected removePlotSubscriptions(plot: HasPlotId): void { // subjects - for (const subjectMap of [this.layerData$, this.layerDataState$]) { + for (const subjectMap of [this.plotData$, this.plotDataState$]) { subjectMap.get(plot.id).complete(); subjectMap.delete(plot.id); } diff --git a/projects/wave-core-new/src/lib/wave-core.module.ts b/projects/wave-core-new/src/lib/wave-core.module.ts index d2c1a5ce..c9e6e6f2 100644 --- a/projects/wave-core-new/src/lib/wave-core.module.ts +++ b/projects/wave-core-new/src/lib/wave-core.module.ts @@ -90,6 +90,7 @@ import {LineageGraphComponent} from './provenance/lineage-graph/lineage-graph.co import {MeanRasterPixelValuesOverTimeDialogComponent} from './operators/dialogs/mean-raster-pixel-values-over-time-dialog/mean-raster-pixel-values-over-time-dialog.component'; import {RasterVectorJoinComponent} from './operators/dialogs/raster-vector-join/raster-vector-join.component'; import {PointInPolygonFilterOperatorComponent} from './operators/dialogs/point-in-polygon-filter/point-in-polygon-filter.component'; +import {UploadComponent} from './datasets/upload/upload.component'; import {DataTableComponent} from './datatable/table/table.component'; import {TabsComponent} from './tabs/tabs.component'; import {PortalModule} from '@angular/cdk/portal'; @@ -189,6 +190,7 @@ const WAVE_COMPONENTS = [ TabsComponent, TimeConfigComponent, TimeInputComponent, + UploadComponent, VatLogoComponent, VectorLegendComponent, VegaViewerComponent, diff --git a/projects/wave-core-new/src/public-api.ts b/projects/wave-core-new/src/public-api.ts index 8bf7a88e..e09842fc 100644 --- a/projects/wave-core-new/src/public-api.ts +++ b/projects/wave-core-new/src/public-api.ts @@ -21,6 +21,7 @@ export * from './lib/util/services/random-color.service'; export * from './lib/datasets/add-data/add-data.component'; export * from './lib/datasets/dataset-list/dataset-list.component'; export * from './lib/datasets/dataset/dataset.component'; +export * from './lib/datasets/upload/upload.component'; export * from './lib/datatable/table/table.component'; export * from './lib/dialogs/dialog-header/dialog-header.component'; export * from './lib/dialogs/dialog-help/dialog-help.component'; diff --git a/projects/wave-core-new/tsconfig.lib.json b/projects/wave-core-new/tsconfig.lib.json index 019b9d4a..e0ff216c 100644 --- a/projects/wave-core-new/tsconfig.lib.json +++ b/projects/wave-core-new/tsconfig.lib.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "../../out-tsc/lib", + "declarationMap": true, "target": "es2015", "declaration": true, "inlineSources": true, diff --git a/projects/wave-core-new/tsconfig.lib.prod.json b/projects/wave-core-new/tsconfig.lib.prod.json index 627e8823..9fde9f85 100644 --- a/projects/wave-core-new/tsconfig.lib.prod.json +++ b/projects/wave-core-new/tsconfig.lib.prod.json @@ -1,4 +1,7 @@ { "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declarationMap": false + }, "angularCompilerOptions": {} } diff --git a/projects/wave-core/.eslintrc.json b/projects/wave-core/.eslintrc.json deleted file mode 100644 index eff7f7bd..00000000 --- a/projects/wave-core/.eslintrc.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": ["projects/wave-core/tsconfig.lib.json", "projects/wave-core/tsconfig.spec.json"], - "createDefaultProgram": true - }, - "rules": {} - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/wave-core/README.md b/projects/wave-core/README.md deleted file mode 100644 index 9d36cb4e..00000000 --- a/projects/wave-core/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# WaveCore - -This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.0.6. - -## Code scaffolding - -Run `ng generate component component-name --project wave-core` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project wave-core`. - -> Note: Don't forget to add `--project wave-core` or else it will be added to the default project in your `angular.json` file. - -## Build - -Run `ng build wave-core` to build the project. The build artifacts will be stored in the `dist/` directory. - -## Publishing - -After building your library with `ng build wave-core`, go to the dist folder `cd dist/wave-core` and run `npm publish`. - -## Running unit tests - -Run `ng test wave-core` to execute the unit tests via [Karma](https://karma-runner.github.io). - -## 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). diff --git a/projects/wave-core/assets/.gitignore b/projects/wave-core/assets/.gitignore deleted file mode 100644 index d344ba6b..00000000 --- a/projects/wave-core/assets/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.json diff --git a/projects/wave-core/assets/.gitkeep b/projects/wave-core/assets/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/assets/config.json.blueprint b/projects/wave-core/assets/config.json.blueprint deleted file mode 100644 index 0967ef42..00000000 --- a/projects/wave-core/assets/config.json.blueprint +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/projects/wave-core/assets/countries.geojson b/projects/wave-core/assets/countries.geojson deleted file mode 100644 index aee18b93..00000000 --- a/projects/wave-core/assets/countries.geojson +++ /dev/null @@ -1,183 +0,0 @@ -{"type":"FeatureCollection","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"features":[ -{"type":"Feature","id":"BACKGROUND","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-180.0,-90.0],[180.0,-90.0],[180.0,90.0],[-180.0,90.0],[-180.0,-90.0]]]}}, -{"type":"Feature","id":"AFG","properties":{"name":"Afghanistan"},"geometry":{"type":"Polygon","coordinates":[[[61.210817,35.650072],[62.230651,35.270664],[62.984662,35.404041],[63.193538,35.857166],[63.982896,36.007957],[64.546479,36.312073],[64.746105,37.111818],[65.588948,37.305217],[65.745631,37.661164],[66.217385,37.39379],[66.518607,37.362784],[67.075782,37.356144],[67.83,37.144994],[68.135562,37.023115],[68.859446,37.344336],[69.196273,37.151144],[69.518785,37.608997],[70.116578,37.588223],[70.270574,37.735165],[70.376304,38.138396],[70.806821,38.486282],[71.348131,38.258905],[71.239404,37.953265],[71.541918,37.905774],[71.448693,37.065645],[71.844638,36.738171],[72.193041,36.948288],[72.63689,37.047558],[73.260056,37.495257],[73.948696,37.421566],[74.980002,37.41999],[75.158028,37.133031],[74.575893,37.020841],[74.067552,36.836176],[72.920025,36.720007],[71.846292,36.509942],[71.262348,36.074388],[71.498768,35.650563],[71.613076,35.153203],[71.115019,34.733126],[71.156773,34.348911],[70.881803,33.988856],[69.930543,34.02012],[70.323594,33.358533],[69.687147,33.105499],[69.262522,32.501944],[69.317764,31.901412],[68.926677,31.620189],[68.556932,31.71331],[67.792689,31.58293],[67.683394,31.303154],[66.938891,31.304911],[66.381458,30.738899],[66.346473,29.887943],[65.046862,29.472181],[64.350419,29.560031],[64.148002,29.340819],[63.550261,29.468331],[62.549857,29.318572],[60.874248,29.829239],[61.781222,30.73585],[61.699314,31.379506],[60.941945,31.548075],[60.863655,32.18292],[60.536078,32.981269],[60.9637,33.528832],[60.52843,33.676446],[60.803193,34.404102],[61.210817,35.650072]]]}}, -{"type":"Feature","id":"AGO","properties":{"name":"Angola"},"geometry":{"type":"MultiPolygon","coordinates":[[[[16.326528,-5.87747],[16.57318,-6.622645],[16.860191,-7.222298],[17.089996,-7.545689],[17.47297,-8.068551],[18.134222,-7.987678],[18.464176,-7.847014],[19.016752,-7.988246],[19.166613,-7.738184],[19.417502,-7.155429],[20.037723,-7.116361],[20.091622,-6.94309],[20.601823,-6.939318],[20.514748,-7.299606],[21.728111,-7.290872],[21.746456,-7.920085],[21.949131,-8.305901],[21.801801,-8.908707],[21.875182,-9.523708],[22.208753,-9.894796],[22.155268,-11.084801],[22.402798,-10.993075],[22.837345,-11.017622],[23.456791,-10.867863],[23.912215,-10.926826],[24.017894,-11.237298],[23.904154,-11.722282],[24.079905,-12.191297],[23.930922,-12.565848],[24.016137,-12.911046],[21.933886,-12.898437],[21.887843,-16.08031],[22.562478,-16.898451],[23.215048,-17.523116],[21.377176,-17.930636],[18.956187,-17.789095],[18.263309,-17.309951],[14.209707,-17.353101],[14.058501,-17.423381],[13.462362,-16.971212],[12.814081,-16.941343],[12.215461,-17.111668],[11.734199,-17.301889],[11.640096,-16.673142],[11.778537,-15.793816],[12.123581,-14.878316],[12.175619,-14.449144],[12.500095,-13.5477],[12.738479,-13.137906],[13.312914,-12.48363],[13.633721,-12.038645],[13.738728,-11.297863],[13.686379,-10.731076],[13.387328,-10.373578],[13.120988,-9.766897],[12.87537,-9.166934],[12.929061,-8.959091],[13.236433,-8.562629],[12.93304,-7.596539],[12.728298,-6.927122],[12.227347,-6.294448],[12.322432,-6.100092],[12.735171,-5.965682],[13.024869,-5.984389],[13.375597,-5.864241],[16.326528,-5.87747]]],[[[12.436688,-5.684304],[12.182337,-5.789931],[11.914963,-5.037987],[12.318608,-4.60623],[12.62076,-4.438023],[12.995517,-4.781103],[12.631612,-4.991271],[12.468004,-5.248362],[12.436688,-5.684304]]]]}}, -{"type":"Feature","id":"ALB","properties":{"name":"Albania"},"geometry":{"type":"Polygon","coordinates":[[[20.590247,41.855404],[20.463175,41.515089],[20.605182,41.086226],[21.02004,40.842727],[20.99999,40.580004],[20.674997,40.435],[20.615,40.110007],[20.150016,39.624998],[19.98,39.694993],[19.960002,39.915006],[19.406082,40.250773],[19.319059,40.72723],[19.40355,41.409566],[19.540027,41.719986],[19.371769,41.877548],[19.304486,42.195745],[19.738051,42.688247],[19.801613,42.500093],[20.0707,42.58863],[20.283755,42.32026],[20.52295,42.21787],[20.590247,41.855404]]]}}, -{"type":"Feature","id":"ARE","properties":{"name":"United Arab Emirates"},"geometry":{"type":"Polygon","coordinates":[[[51.579519,24.245497],[51.757441,24.294073],[51.794389,24.019826],[52.577081,24.177439],[53.404007,24.151317],[54.008001,24.121758],[54.693024,24.797892],[55.439025,25.439145],[56.070821,26.055464],[56.261042,25.714606],[56.396847,24.924732],[55.886233,24.920831],[55.804119,24.269604],[55.981214,24.130543],[55.528632,23.933604],[55.525841,23.524869],[55.234489,23.110993],[55.208341,22.70833],[55.006803,22.496948],[52.000733,23.001154],[51.617708,24.014219],[51.579519,24.245497]]]}}, -{"type":"Feature","id":"ARG","properties":{"name":"Argentina"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-65.5,-55.2],[-66.45,-55.25],[-66.95992,-54.89681],[-67.56244,-54.87001],[-68.63335,-54.8695],[-68.63401,-52.63637],[-68.25,-53.1],[-67.75,-53.85],[-66.45,-54.45],[-65.05,-54.7],[-65.5,-55.2]]],[[[-64.964892,-22.075862],[-64.377021,-22.798091],[-63.986838,-21.993644],[-62.846468,-22.034985],[-62.685057,-22.249029],[-60.846565,-23.880713],[-60.028966,-24.032796],[-58.807128,-24.771459],[-57.777217,-25.16234],[-57.63366,-25.603657],[-58.618174,-27.123719],[-57.60976,-27.395899],[-56.486702,-27.548499],[-55.695846,-27.387837],[-54.788795,-26.621786],[-54.625291,-25.739255],[-54.13005,-25.547639],[-53.628349,-26.124865],[-53.648735,-26.923473],[-54.490725,-27.474757],[-55.162286,-27.881915],[-56.2909,-28.852761],[-57.625133,-30.216295],[-57.874937,-31.016556],[-58.14244,-32.044504],[-58.132648,-33.040567],[-58.349611,-33.263189],[-58.427074,-33.909454],[-58.495442,-34.43149],[-57.22583,-35.288027],[-57.362359,-35.97739],[-56.737487,-36.413126],[-56.788285,-36.901572],[-57.749157,-38.183871],[-59.231857,-38.72022],[-61.237445,-38.928425],[-62.335957,-38.827707],[-62.125763,-39.424105],[-62.330531,-40.172586],[-62.145994,-40.676897],[-62.745803,-41.028761],[-63.770495,-41.166789],[-64.73209,-40.802677],[-65.118035,-41.064315],[-64.978561,-42.058001],[-64.303408,-42.359016],[-63.755948,-42.043687],[-63.458059,-42.563138],[-64.378804,-42.873558],[-65.181804,-43.495381],[-65.328823,-44.501366],[-65.565269,-45.036786],[-66.509966,-45.039628],[-67.293794,-45.551896],[-67.580546,-46.301773],[-66.597066,-47.033925],[-65.641027,-47.236135],[-65.985088,-48.133289],[-67.166179,-48.697337],[-67.816088,-49.869669],[-68.728745,-50.264218],[-69.138539,-50.73251],[-68.815561,-51.771104],[-68.149995,-52.349983],[-68.571545,-52.299444],[-69.498362,-52.142761],[-71.914804,-52.009022],[-72.329404,-51.425956],[-72.309974,-50.67701],[-72.975747,-50.74145],[-73.328051,-50.378785],[-73.415436,-49.318436],[-72.648247,-48.878618],[-72.331161,-48.244238],[-72.447355,-47.738533],[-71.917258,-46.884838],[-71.552009,-45.560733],[-71.659316,-44.973689],[-71.222779,-44.784243],[-71.329801,-44.407522],[-71.793623,-44.207172],[-71.464056,-43.787611],[-71.915424,-43.408565],[-72.148898,-42.254888],[-71.746804,-42.051386],[-71.915734,-40.832339],[-71.680761,-39.808164],[-71.413517,-38.916022],[-70.814664,-38.552995],[-71.118625,-37.576827],[-71.121881,-36.658124],[-70.364769,-36.005089],[-70.388049,-35.169688],[-69.817309,-34.193571],[-69.814777,-33.273886],[-70.074399,-33.09121],[-70.535069,-31.36501],[-69.919008,-30.336339],[-70.01355,-29.367923],[-69.65613,-28.459141],[-69.001235,-27.521214],[-68.295542,-26.89934],[-68.5948,-26.506909],[-68.386001,-26.185016],[-68.417653,-24.518555],[-67.328443,-24.025303],[-66.985234,-22.986349],[-67.106674,-22.735925],[-66.273339,-21.83231],[-64.964892,-22.075862]]]]}}, -{"type":"Feature","id":"ARM","properties":{"name":"Armenia"},"geometry":{"type":"Polygon","coordinates":[[[43.582746,41.092143],[44.97248,41.248129],[45.179496,40.985354],[45.560351,40.81229],[45.359175,40.561504],[45.891907,40.218476],[45.610012,39.899994],[46.034534,39.628021],[46.483499,39.464155],[46.50572,38.770605],[46.143623,38.741201],[45.735379,39.319719],[45.739978,39.473999],[45.298145,39.471751],[45.001987,39.740004],[44.79399,39.713003],[44.400009,40.005],[43.656436,40.253564],[43.752658,40.740201],[43.582746,41.092143]]]}}, -{"type":"Feature","id":"ATA","properties":{"name":"Antarctica"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-59.572095,-80.040179],[-59.865849,-80.549657],[-60.159656,-81.000327],[-62.255393,-80.863178],[-64.488125,-80.921934],[-65.741666,-80.588827],[-65.741666,-80.549657],[-66.290031,-80.255773],[-64.037688,-80.294944],[-61.883246,-80.39287],[-61.138976,-79.981371],[-60.610119,-79.628679],[-59.572095,-80.040179]]],[[[-159.208184,-79.497059],[-161.127601,-79.634209],[-162.439847,-79.281465],[-163.027408,-78.928774],[-163.066604,-78.869966],[-163.712896,-78.595667],[-163.105801,-78.223338],[-161.245113,-78.380176],[-160.246208,-78.693645],[-159.482405,-79.046338],[-159.208184,-79.497059]]],[[[-45.154758,-78.04707],[-43.920828,-78.478103],[-43.48995,-79.08556],[-43.372438,-79.516645],[-43.333267,-80.026123],[-44.880537,-80.339644],[-46.506174,-80.594357],[-48.386421,-80.829485],[-50.482107,-81.025442],[-52.851988,-80.966685],[-54.164259,-80.633528],[-53.987991,-80.222028],[-51.853134,-79.94773],[-50.991326,-79.614623],[-50.364595,-79.183487],[-49.914131,-78.811209],[-49.306959,-78.458569],[-48.660616,-78.047018],[-48.660616,-78.047019],[-48.151396,-78.04707],[-46.662857,-77.831476],[-45.154758,-78.04707]]],[[[-121.211511,-73.50099],[-119.918851,-73.657725],[-118.724143,-73.481353],[-119.292119,-73.834097],[-120.232217,-74.08881],[-121.62283,-74.010468],[-122.621735,-73.657778],[-122.621735,-73.657777],[-122.406245,-73.324619],[-121.211511,-73.50099]]],[[[-125.559566,-73.481353],[-124.031882,-73.873268],[-124.619469,-73.834097],[-125.912181,-73.736118],[-127.28313,-73.461769],[-127.28313,-73.461768],[-126.558472,-73.246226],[-125.559566,-73.481353]]],[[[-98.98155,-71.933334],[-97.884743,-72.070535],[-96.787937,-71.952971],[-96.20035,-72.521205],[-96.983765,-72.442864],[-98.198083,-72.482035],[-99.432013,-72.442864],[-100.783455,-72.50162],[-101.801868,-72.305663],[-102.330725,-71.894164],[-101.703967,-71.717792],[-100.430919,-71.854993],[-98.98155,-71.933334]]],[[[-68.451346,-70.955823],[-68.333834,-71.406493],[-68.510128,-71.798407],[-68.784297,-72.170736],[-69.959471,-72.307885],[-71.075889,-72.503842],[-72.388134,-72.484257],[-71.8985,-72.092343],[-73.073622,-72.229492],[-74.19004,-72.366693],[-74.953895,-72.072757],[-75.012625,-71.661258],[-73.915819,-71.269345],[-73.915819,-71.269344],[-73.230331,-71.15178],[-72.074717,-71.190951],[-71.780962,-70.681473],[-71.72218,-70.309196],[-71.741791,-69.505782],[-71.173815,-69.035475],[-70.253252,-68.87874],[-69.724447,-69.251017],[-69.489422,-69.623346],[-69.058518,-70.074016],[-68.725541,-70.505153],[-68.451346,-70.955823]]],[[[-58.614143,-64.152467],[-59.045073,-64.36801],[-59.789342,-64.211223],[-60.611928,-64.309202],[-61.297416,-64.54433],[-62.0221,-64.799094],[-62.51176,-65.09303],[-62.648858,-65.484942],[-62.590128,-65.857219],[-62.120079,-66.190326],[-62.805567,-66.425505],[-63.74569,-66.503847],[-64.294106,-66.837004],[-64.881693,-67.150474],[-65.508425,-67.58161],[-65.665082,-67.953887],[-65.312545,-68.365335],[-64.783715,-68.678908],[-63.961103,-68.913984],[-63.1973,-69.227556],[-62.785955,-69.619419],[-62.570516,-69.991747],[-62.276736,-70.383661],[-61.806661,-70.716768],[-61.512906,-71.089045],[-61.375809,-72.010074],[-61.081977,-72.382351],[-61.003661,-72.774265],[-60.690269,-73.166179],[-60.827367,-73.695242],[-61.375809,-74.106742],[-61.96337,-74.439848],[-63.295201,-74.576997],[-63.74569,-74.92974],[-64.352836,-75.262847],[-65.860987,-75.635124],[-67.192818,-75.79191],[-68.446282,-76.007452],[-69.797724,-76.222995],[-70.600724,-76.634494],[-72.206776,-76.673665],[-73.969536,-76.634494],[-75.555977,-76.712887],[-77.24037,-76.712887],[-76.926979,-77.104802],[-75.399294,-77.28107],[-74.282876,-77.55542],[-73.656119,-77.908112],[-74.772536,-78.221633],[-76.4961,-78.123654],[-77.925858,-78.378419],[-77.984666,-78.789918],[-78.023785,-79.181833],[-76.848637,-79.514939],[-76.633224,-79.887216],[-75.360097,-80.259545],[-73.244852,-80.416331],[-71.442946,-80.69063],[-70.013163,-81.004151],[-68.191646,-81.317672],[-65.704279,-81.474458],[-63.25603,-81.748757],[-61.552026,-82.042692],[-59.691416,-82.37585],[-58.712121,-82.846106],[-58.222487,-83.218434],[-57.008117,-82.865691],[-55.362894,-82.571755],[-53.619771,-82.258235],[-51.543644,-82.003521],[-49.76135,-81.729171],[-47.273931,-81.709586],[-44.825708,-81.846735],[-42.808363,-82.081915],[-42.16202,-81.65083],[-40.771433,-81.356894],[-38.244818,-81.337309],[-36.26667,-81.121715],[-34.386397,-80.906172],[-32.310296,-80.769023],[-30.097098,-80.592651],[-28.549802,-80.337938],[-29.254901,-79.985195],[-29.685805,-79.632503],[-29.685805,-79.260226],[-31.624808,-79.299397],[-33.681324,-79.456132],[-35.639912,-79.456132],[-35.914107,-79.083855],[-35.77701,-78.339248],[-35.326546,-78.123654],[-33.896763,-77.888526],[-32.212369,-77.65345],[-30.998051,-77.359515],[-29.783732,-77.065579],[-28.882779,-76.673665],[-27.511752,-76.497345],[-26.160336,-76.360144],[-25.474822,-76.281803],[-23.927552,-76.24258],[-22.458598,-76.105431],[-21.224694,-75.909474],[-20.010375,-75.674346],[-18.913543,-75.439218],[-17.522982,-75.125698],[-16.641589,-74.79254],[-15.701491,-74.498604],[-15.40771,-74.106742],[-16.46532,-73.871614],[-16.112784,-73.460114],[-15.446855,-73.146542],[-14.408805,-72.950585],[-13.311973,-72.715457],[-12.293508,-72.401936],[-11.510067,-72.010074],[-11.020433,-71.539767],[-10.295774,-71.265416],[-9.101015,-71.324224],[-8.611381,-71.65733],[-7.416622,-71.696501],[-7.377451,-71.324224],[-6.868232,-70.93231],[-5.790985,-71.030289],[-5.536375,-71.402617],[-4.341667,-71.461373],[-3.048981,-71.285053],[-1.795492,-71.167438],[-0.659489,-71.226246],[-0.228637,-71.637745],[0.868195,-71.304639],[1.886686,-71.128267],[3.022638,-70.991118],[4.139055,-70.853917],[5.157546,-70.618789],[6.273912,-70.462055],[7.13572,-70.246512],[7.742866,-69.893769],[8.48711,-70.148534],[9.525135,-70.011333],[10.249845,-70.48164],[10.817821,-70.834332],[11.953824,-70.638375],[12.404287,-70.246512],[13.422778,-69.972162],[14.734998,-70.030918],[15.126757,-70.403247],[15.949342,-70.030918],[17.026589,-69.913354],[18.201711,-69.874183],[19.259373,-69.893769],[20.375739,-70.011333],[21.452985,-70.07014],[21.923034,-70.403247],[22.569403,-70.697182],[23.666184,-70.520811],[24.841357,-70.48164],[25.977309,-70.48164],[27.093726,-70.462055],[28.09258,-70.324854],[29.150242,-70.20729],[30.031583,-69.93294],[30.971733,-69.75662],[31.990172,-69.658641],[32.754053,-69.384291],[33.302443,-68.835642],[33.870419,-68.502588],[34.908495,-68.659271],[35.300202,-69.012014],[36.16201,-69.247142],[37.200035,-69.168748],[37.905108,-69.52144],[38.649404,-69.776205],[39.667894,-69.541077],[40.020431,-69.109941],[40.921358,-68.933621],[41.959434,-68.600514],[42.938702,-68.463313],[44.113876,-68.267408],[44.897291,-68.051866],[45.719928,-67.816738],[46.503343,-67.601196],[47.44344,-67.718759],[48.344419,-67.366068],[48.990736,-67.091718],[49.930885,-67.111303],[50.753471,-66.876175],[50.949325,-66.523484],[51.791547,-66.249133],[52.614133,-66.053176],[53.613038,-65.89639],[54.53355,-65.818049],[55.414943,-65.876805],[56.355041,-65.974783],[57.158093,-66.249133],[57.255968,-66.680218],[58.137361,-67.013324],[58.744508,-67.287675],[59.939318,-67.405239],[60.605221,-67.679589],[61.427806,-67.953887],[62.387489,-68.012695],[63.19049,-67.816738],[64.052349,-67.405239],[64.992447,-67.620729],[65.971715,-67.738345],[66.911864,-67.855909],[67.891133,-67.934302],[68.890038,-67.934302],[69.712624,-68.972791],[69.673453,-69.227556],[69.555941,-69.678226],[68.596258,-69.93294],[67.81274,-70.305268],[67.949889,-70.697182],[69.066307,-70.677545],[68.929157,-71.069459],[68.419989,-71.441788],[67.949889,-71.853287],[68.71377,-72.166808],[69.869307,-72.264787],[71.024895,-72.088415],[71.573285,-71.696501],[71.906288,-71.324224],[72.454627,-71.010703],[73.08141,-70.716768],[73.33602,-70.364024],[73.864877,-69.874183],[74.491557,-69.776205],[75.62756,-69.737034],[76.626465,-69.619419],[77.644904,-69.462684],[78.134539,-69.07077],[78.428371,-68.698441],[79.113859,-68.326216],[80.093127,-68.071503],[80.93535,-67.875546],[81.483792,-67.542388],[82.051767,-67.366068],[82.776426,-67.209282],[83.775331,-67.30726],[84.676206,-67.209282],[85.655527,-67.091718],[86.752359,-67.150474],[87.477017,-66.876175],[87.986289,-66.209911],[88.358411,-66.484261],[88.828408,-66.954568],[89.67063,-67.150474],[90.630365,-67.228867],[91.5901,-67.111303],[92.608539,-67.189696],[93.548637,-67.209282],[94.17542,-67.111303],[95.017591,-67.170111],[95.781472,-67.385653],[96.682399,-67.248504],[97.759646,-67.248504],[98.68021,-67.111303],[99.718182,-67.248504],[100.384188,-66.915346],[100.893356,-66.58224],[101.578896,-66.30789],[102.832411,-65.563284],[103.478676,-65.700485],[104.242557,-65.974783],[104.90846,-66.327527],[106.181561,-66.934931],[107.160881,-66.954568],[108.081393,-66.954568],[109.15864,-66.837004],[110.235835,-66.699804],[111.058472,-66.425505],[111.74396,-66.13157],[112.860378,-66.092347],[113.604673,-65.876805],[114.388088,-66.072762],[114.897308,-66.386283],[115.602381,-66.699804],[116.699161,-66.660633],[117.384701,-66.915346],[118.57946,-67.170111],[119.832924,-67.268089],[120.871,-67.189696],[121.654415,-66.876175],[122.320369,-66.562654],[123.221296,-66.484261],[124.122274,-66.621462],[125.160247,-66.719389],[126.100396,-66.562654],[127.001427,-66.562654],[127.882768,-66.660633],[128.80328,-66.758611],[129.704259,-66.58224],[130.781454,-66.425505],[131.799945,-66.386283],[132.935896,-66.386283],[133.85646,-66.288304],[134.757387,-66.209963],[135.031582,-65.72007],[135.070753,-65.308571],[135.697485,-65.582869],[135.873805,-66.033591],[136.206705,-66.44509],[136.618049,-66.778197],[137.460271,-66.954568],[138.596223,-66.895761],[139.908442,-66.876175],[140.809421,-66.817367],[142.121692,-66.817367],[143.061842,-66.797782],[144.374061,-66.837004],[145.490427,-66.915346],[146.195552,-67.228867],[145.999699,-67.601196],[146.646067,-67.895131],[147.723263,-68.130259],[148.839629,-68.385024],[150.132314,-68.561292],[151.483705,-68.71813],[152.502247,-68.874813],[153.638199,-68.894502],[154.284567,-68.561292],[155.165857,-68.835642],[155.92979,-69.149215],[156.811132,-69.384291],[158.025528,-69.482269],[159.181013,-69.599833],[159.670699,-69.991747],[160.80665,-70.226875],[161.570479,-70.579618],[162.686897,-70.736353],[163.842434,-70.716768],[164.919681,-70.775524],[166.11444,-70.755938],[167.309095,-70.834332],[168.425616,-70.971481],[169.463589,-71.20666],[170.501665,-71.402617],[171.20679,-71.696501],[171.089227,-72.088415],[170.560422,-72.441159],[170.109958,-72.891829],[169.75737,-73.24452],[169.287321,-73.65602],[167.975101,-73.812806],[167.387489,-74.165498],[166.094803,-74.38104],[165.644391,-74.772954],[164.958851,-75.145283],[164.234193,-75.458804],[163.822797,-75.870303],[163.568239,-76.24258],[163.47026,-76.693302],[163.489897,-77.065579],[164.057873,-77.457442],[164.273363,-77.82977],[164.743464,-78.182514],[166.604126,-78.319611],[166.995781,-78.750748],[165.193876,-78.907483],[163.666217,-79.123025],[161.766385,-79.162248],[160.924162,-79.730482],[160.747894,-80.200737],[160.316964,-80.573066],[159.788211,-80.945395],[161.120016,-81.278501],[161.629287,-81.690001],[162.490992,-82.062278],[163.705336,-82.395435],[165.095949,-82.708956],[166.604126,-83.022477],[168.895665,-83.335998],[169.404782,-83.825891],[172.283934,-84.041433],[172.477049,-84.117914],[173.224083,-84.41371],[175.985672,-84.158997],[178.277212,-84.472518],[180,-84.71338],[-179.942499,-84.721443],[-179.058677,-84.139412],[-177.256772,-84.452933],[-177.140807,-84.417941],[-176.084673,-84.099259],[-175.947235,-84.110449],[-175.829882,-84.117914],[-174.382503,-84.534323],[-173.116559,-84.117914],[-172.889106,-84.061019],[-169.951223,-83.884647],[-168.999989,-84.117914],[-168.530199,-84.23739],[-167.022099,-84.570497],[-164.182144,-84.82521],[-161.929775,-85.138731],[-158.07138,-85.37391],[-155.192253,-85.09956],[-150.942099,-85.295517],[-148.533073,-85.609038],[-145.888918,-85.315102],[-143.107718,-85.040752],[-142.892279,-84.570497],[-146.829068,-84.531274],[-150.060732,-84.296146],[-150.902928,-83.904232],[-153.586201,-83.68869],[-153.409907,-83.23802],[-153.037759,-82.82652],[-152.665637,-82.454192],[-152.861517,-82.042692],[-154.526299,-81.768394],[-155.29018,-81.41565],[-156.83745,-81.102129],[-154.408787,-81.160937],[-152.097662,-81.004151],[-150.648293,-81.337309],[-148.865998,-81.043373],[-147.22075,-80.671045],[-146.417749,-80.337938],[-146.770286,-79.926439],[-148.062947,-79.652089],[-149.531901,-79.358205],[-151.588416,-79.299397],[-153.390322,-79.162248],[-155.329376,-79.064269],[-155.975668,-78.69194],[-157.268302,-78.378419],[-158.051768,-78.025676],[-158.365134,-76.889207],[-157.875474,-76.987238],[-156.974573,-77.300759],[-155.329376,-77.202728],[-153.742832,-77.065579],[-152.920247,-77.496664],[-151.33378,-77.398737],[-150.00195,-77.183143],[-148.748486,-76.908845],[-147.612483,-76.575738],[-146.104409,-76.47776],[-146.143528,-76.105431],[-146.496091,-75.733154],[-146.20231,-75.380411],[-144.909624,-75.204039],[-144.322037,-75.537197],[-142.794353,-75.34124],[-141.638764,-75.086475],[-140.209007,-75.06689],[-138.85759,-74.968911],[-137.5062,-74.733783],[-136.428901,-74.518241],[-135.214583,-74.302699],[-134.431194,-74.361455],[-133.745654,-74.439848],[-132.257168,-74.302699],[-130.925311,-74.479019],[-129.554284,-74.459433],[-128.242038,-74.322284],[-126.890622,-74.420263],[-125.402082,-74.518241],[-124.011496,-74.479019],[-122.562152,-74.498604],[-121.073613,-74.518241],[-119.70256,-74.479019],[-118.684145,-74.185083],[-117.469801,-74.028348],[-116.216312,-74.243891],[-115.021552,-74.067519],[-113.944331,-73.714828],[-113.297988,-74.028348],[-112.945452,-74.38104],[-112.299083,-74.714198],[-111.261059,-74.420263],[-110.066325,-74.79254],[-108.714909,-74.910103],[-107.559346,-75.184454],[-106.149148,-75.125698],[-104.876074,-74.949326],[-103.367949,-74.988497],[-102.016507,-75.125698],[-100.645531,-75.302018],[-100.1167,-74.870933],[-100.763043,-74.537826],[-101.252703,-74.185083],[-102.545337,-74.106742],[-103.113313,-73.734413],[-103.328752,-73.362084],[-103.681289,-72.61753],[-102.917485,-72.754679],[-101.60524,-72.813436],[-100.312528,-72.754679],[-99.13738,-72.911414],[-98.118889,-73.20535],[-97.688037,-73.558041],[-96.336595,-73.616849],[-95.043961,-73.4797],[-93.672907,-73.283743],[-92.439003,-73.166179],[-91.420564,-73.401307],[-90.088733,-73.322914],[-89.226951,-72.558722],[-88.423951,-73.009393],[-87.268337,-73.185764],[-86.014822,-73.087786],[-85.192236,-73.4797],[-83.879991,-73.518871],[-82.665646,-73.636434],[-81.470913,-73.851977],[-80.687447,-73.4797],[-80.295791,-73.126956],[-79.296886,-73.518871],[-77.925858,-73.420892],[-76.907367,-73.636434],[-76.221879,-73.969541],[-74.890049,-73.871614],[-73.852024,-73.65602],[-72.833533,-73.401307],[-71.619215,-73.264157],[-70.209042,-73.146542],[-68.935916,-73.009393],[-67.956622,-72.79385],[-67.369061,-72.480329],[-67.134036,-72.049244],[-67.251548,-71.637745],[-67.56494,-71.245831],[-67.917477,-70.853917],[-68.230843,-70.462055],[-68.485452,-70.109311],[-68.544209,-69.717397],[-68.446282,-69.325535],[-67.976233,-68.953206],[-67.5845,-68.541707],[-67.427843,-68.149844],[-67.62367,-67.718759],[-67.741183,-67.326845],[-67.251548,-66.876175],[-66.703184,-66.58224],[-66.056815,-66.209963],[-65.371327,-65.89639],[-64.568276,-65.602506],[-64.176542,-65.171423],[-63.628152,-64.897073],[-63.001394,-64.642308],[-62.041686,-64.583552],[-61.414928,-64.270031],[-60.709855,-64.074074],[-59.887269,-63.95651],[-59.162585,-63.701745],[-58.594557,-63.388224],[-57.811143,-63.27066],[-57.223582,-63.525425],[-57.59573,-63.858532],[-58.614143,-64.152467]]]]}}, -{"type":"Feature","id":"ATF","properties":{"name":"French Southern and Antarctic Lands"},"geometry":{"type":"Polygon","coordinates":[[[68.935,-48.625],[69.58,-48.94],[70.525,-49.065],[70.56,-49.255],[70.28,-49.71],[68.745,-49.775],[68.72,-49.2425],[68.8675,-48.83],[68.935,-48.625]]]}}, -{"type":"Feature","id":"AUS","properties":{"name":"Australia"},"geometry":{"type":"MultiPolygon","coordinates":[[[[145.397978,-40.792549],[146.364121,-41.137695],[146.908584,-41.000546],[147.689259,-40.808258],[148.289068,-40.875438],[148.359865,-42.062445],[148.017301,-42.407024],[147.914052,-43.211522],[147.564564,-42.937689],[146.870343,-43.634597],[146.663327,-43.580854],[146.048378,-43.549745],[145.43193,-42.693776],[145.29509,-42.03361],[144.718071,-41.162552],[144.743755,-40.703975],[145.397978,-40.792549]]],[[[143.561811,-13.763656],[143.922099,-14.548311],[144.563714,-14.171176],[144.894908,-14.594458],[145.374724,-14.984976],[145.271991,-15.428205],[145.48526,-16.285672],[145.637033,-16.784918],[145.888904,-16.906926],[146.160309,-17.761655],[146.063674,-18.280073],[146.387478,-18.958274],[147.471082,-19.480723],[148.177602,-19.955939],[148.848414,-20.39121],[148.717465,-20.633469],[149.28942,-21.260511],[149.678337,-22.342512],[150.077382,-22.122784],[150.482939,-22.556142],[150.727265,-22.402405],[150.899554,-23.462237],[151.609175,-24.076256],[152.07354,-24.457887],[152.855197,-25.267501],[153.136162,-26.071173],[153.161949,-26.641319],[153.092909,-27.2603],[153.569469,-28.110067],[153.512108,-28.995077],[153.339095,-29.458202],[153.069241,-30.35024],[153.089602,-30.923642],[152.891578,-31.640446],[152.450002,-32.550003],[151.709117,-33.041342],[151.343972,-33.816023],[151.010555,-34.31036],[150.714139,-35.17346],[150.32822,-35.671879],[150.075212,-36.420206],[149.946124,-37.109052],[149.997284,-37.425261],[149.423882,-37.772681],[148.304622,-37.809061],[147.381733,-38.219217],[146.922123,-38.606532],[146.317922,-39.035757],[145.489652,-38.593768],[144.876976,-38.417448],[145.032212,-37.896188],[144.485682,-38.085324],[143.609974,-38.809465],[142.745427,-38.538268],[142.17833,-38.380034],[141.606582,-38.308514],[140.638579,-38.019333],[139.992158,-37.402936],[139.806588,-36.643603],[139.574148,-36.138362],[139.082808,-35.732754],[138.120748,-35.612296],[138.449462,-35.127261],[138.207564,-34.384723],[137.71917,-35.076825],[136.829406,-35.260535],[137.352371,-34.707339],[137.503886,-34.130268],[137.890116,-33.640479],[137.810328,-32.900007],[136.996837,-33.752771],[136.372069,-34.094766],[135.989043,-34.890118],[135.208213,-34.47867],[135.239218,-33.947953],[134.613417,-33.222778],[134.085904,-32.848072],[134.273903,-32.617234],[132.990777,-32.011224],[132.288081,-31.982647],[131.326331,-31.495803],[129.535794,-31.590423],[128.240938,-31.948489],[127.102867,-32.282267],[126.148714,-32.215966],[125.088623,-32.728751],[124.221648,-32.959487],[124.028947,-33.483847],[123.659667,-33.890179],[122.811036,-33.914467],[122.183064,-34.003402],[121.299191,-33.821036],[120.580268,-33.930177],[119.893695,-33.976065],[119.298899,-34.509366],[119.007341,-34.464149],[118.505718,-34.746819],[118.024972,-35.064733],[117.295507,-35.025459],[116.625109,-35.025097],[115.564347,-34.386428],[115.026809,-34.196517],[115.048616,-33.623425],[115.545123,-33.487258],[115.714674,-33.259572],[115.679379,-32.900369],[115.801645,-32.205062],[115.689611,-31.612437],[115.160909,-30.601594],[114.997043,-30.030725],[115.040038,-29.461095],[114.641974,-28.810231],[114.616498,-28.516399],[114.173579,-28.118077],[114.048884,-27.334765],[113.477498,-26.543134],[113.338953,-26.116545],[113.778358,-26.549025],[113.440962,-25.621278],[113.936901,-25.911235],[114.232852,-26.298446],[114.216161,-25.786281],[113.721255,-24.998939],[113.625344,-24.683971],[113.393523,-24.384764],[113.502044,-23.80635],[113.706993,-23.560215],[113.843418,-23.059987],[113.736552,-22.475475],[114.149756,-21.755881],[114.225307,-22.517488],[114.647762,-21.82952],[115.460167,-21.495173],[115.947373,-21.068688],[116.711615,-20.701682],[117.166316,-20.623599],[117.441545,-20.746899],[118.229559,-20.374208],[118.836085,-20.263311],[118.987807,-20.044203],[119.252494,-19.952942],[119.805225,-19.976506],[120.85622,-19.683708],[121.399856,-19.239756],[121.655138,-18.705318],[122.241665,-18.197649],[122.286624,-17.798603],[122.312772,-17.254967],[123.012574,-16.4052],[123.433789,-17.268558],[123.859345,-17.069035],[123.503242,-16.596506],[123.817073,-16.111316],[124.258287,-16.327944],[124.379726,-15.56706],[124.926153,-15.0751],[125.167275,-14.680396],[125.670087,-14.51007],[125.685796,-14.230656],[126.125149,-14.347341],[126.142823,-14.095987],[126.582589,-13.952791],[127.065867,-13.817968],[127.804633,-14.276906],[128.35969,-14.86917],[128.985543,-14.875991],[129.621473,-14.969784],[129.4096,-14.42067],[129.888641,-13.618703],[130.339466,-13.357376],[130.183506,-13.10752],[130.617795,-12.536392],[131.223495,-12.183649],[131.735091,-12.302453],[132.575298,-12.114041],[132.557212,-11.603012],[131.824698,-11.273782],[132.357224,-11.128519],[133.019561,-11.376411],[133.550846,-11.786515],[134.393068,-12.042365],[134.678632,-11.941183],[135.298491,-12.248606],[135.882693,-11.962267],[136.258381,-12.049342],[136.492475,-11.857209],[136.95162,-12.351959],[136.685125,-12.887223],[136.305407,-13.29123],[135.961758,-13.324509],[136.077617,-13.724278],[135.783836,-14.223989],[135.428664,-14.715432],[135.500184,-14.997741],[136.295175,-15.550265],[137.06536,-15.870762],[137.580471,-16.215082],[138.303217,-16.807604],[138.585164,-16.806622],[139.108543,-17.062679],[139.260575,-17.371601],[140.215245,-17.710805],[140.875463,-17.369069],[141.07111,-16.832047],[141.274095,-16.38887],[141.398222,-15.840532],[141.702183,-15.044921],[141.56338,-14.561333],[141.63552,-14.270395],[141.519869,-13.698078],[141.65092,-12.944688],[141.842691,-12.741548],[141.68699,-12.407614],[141.928629,-11.877466],[142.118488,-11.328042],[142.143706,-11.042737],[142.51526,-10.668186],[142.79731,-11.157355],[142.866763,-11.784707],[143.115947,-11.90563],[143.158632,-12.325656],[143.522124,-12.834358],[143.597158,-13.400422],[143.561811,-13.763656]]]]}}, -{"type":"Feature","id":"AUT","properties":{"name":"Austria"},"geometry":{"type":"Polygon","coordinates":[[[16.979667,48.123497],[16.903754,47.714866],[16.340584,47.712902],[16.534268,47.496171],[16.202298,46.852386],[16.011664,46.683611],[15.137092,46.658703],[14.632472,46.431817],[13.806475,46.509306],[12.376485,46.767559],[12.153088,47.115393],[11.164828,46.941579],[11.048556,46.751359],[10.442701,46.893546],[9.932448,46.920728],[9.47997,47.10281],[9.632932,47.347601],[9.594226,47.525058],[9.896068,47.580197],[10.402084,47.302488],[10.544504,47.566399],[11.426414,47.523766],[12.141357,47.703083],[12.62076,47.672388],[12.932627,47.467646],[13.025851,47.637584],[12.884103,48.289146],[13.243357,48.416115],[13.595946,48.877172],[14.338898,48.555305],[14.901447,48.964402],[15.253416,49.039074],[16.029647,48.733899],[16.499283,48.785808],[16.960288,48.596982],[16.879983,48.470013],[16.979667,48.123497]]]}}, -{"type":"Feature","id":"AZE","properties":{"name":"Azerbaijan"},"geometry":{"type":"MultiPolygon","coordinates":[[[[45.001987,39.740004],[45.298145,39.471751],[45.739978,39.473999],[45.735379,39.319719],[46.143623,38.741201],[45.457722,38.874139],[44.952688,39.335765],[44.79399,39.713003],[45.001987,39.740004]]],[[[47.373315,41.219732],[47.815666,41.151416],[47.987283,41.405819],[48.584353,41.80887],[49.110264,41.282287],[49.618915,40.572924],[50.08483,40.526157],[50.392821,40.256561],[49.569202,40.176101],[49.395259,39.399482],[49.223228,39.049219],[48.856532,38.815486],[48.883249,38.320245],[48.634375,38.270378],[48.010744,38.794015],[48.355529,39.288765],[48.060095,39.582235],[47.685079,39.508364],[46.50572,38.770605],[46.483499,39.464155],[46.034534,39.628021],[45.610012,39.899994],[45.891907,40.218476],[45.359175,40.561504],[45.560351,40.81229],[45.179496,40.985354],[44.97248,41.248129],[45.217426,41.411452],[45.962601,41.123873],[46.501637,41.064445],[46.637908,41.181673],[46.145432,41.722802],[46.404951,41.860675],[46.686071,41.827137],[47.373315,41.219732]]]]}}, -{"type":"Feature","id":"BDI","properties":{"name":"Burundi"},"geometry":{"type":"Polygon","coordinates":[[[29.339998,-4.499983],[29.276384,-3.293907],[29.024926,-2.839258],[29.632176,-2.917858],[29.938359,-2.348487],[30.469696,-2.413858],[30.527677,-2.807632],[30.743013,-3.034285],[30.752263,-3.35933],[30.50556,-3.568567],[30.116333,-4.090138],[29.753512,-4.452389],[29.339998,-4.499983]]]}}, -{"type":"Feature","id":"BEL","properties":{"name":"Belgium"},"geometry":{"type":"Polygon","coordinates":[[[3.314971,51.345781],[4.047071,51.267259],[4.973991,51.475024],[5.606976,51.037298],[6.156658,50.803721],[6.043073,50.128052],[5.782417,50.090328],[5.674052,49.529484],[4.799222,49.985373],[4.286023,49.907497],[3.588184,50.378992],[3.123252,50.780363],[2.658422,50.796848],[2.513573,51.148506],[3.314971,51.345781]]]}}, -{"type":"Feature","id":"BEN","properties":{"name":"Benin"},"geometry":{"type":"Polygon","coordinates":[[[2.691702,6.258817],[1.865241,6.142158],[1.618951,6.832038],[1.664478,9.12859],[1.463043,9.334624],[1.425061,9.825395],[1.077795,10.175607],[0.772336,10.470808],[0.899563,10.997339],[1.24347,11.110511],[1.447178,11.547719],[1.935986,11.64115],[2.154474,11.94015],[2.490164,12.233052],[2.848643,12.235636],[3.61118,11.660167],[3.572216,11.327939],[3.797112,10.734746],[3.60007,10.332186],[3.705438,10.06321],[3.220352,9.444153],[2.912308,9.137608],[2.723793,8.506845],[2.749063,7.870734],[2.691702,6.258817]]]}}, -{"type":"Feature","id":"BFA","properties":{"name":"Burkina Faso"},"geometry":{"type":"Polygon","coordinates":[[[-2.827496,9.642461],[-3.511899,9.900326],[-3.980449,9.862344],[-4.330247,9.610835],[-4.779884,9.821985],[-4.954653,10.152714],[-5.404342,10.370737],[-5.470565,10.95127],[-5.197843,11.375146],[-5.220942,11.713859],[-4.427166,12.542646],[-4.280405,13.228444],[-4.006391,13.472485],[-3.522803,13.337662],[-3.103707,13.541267],[-2.967694,13.79815],[-2.191825,14.246418],[-2.001035,14.559008],[-1.066363,14.973815],[-0.515854,15.116158],[-0.266257,14.924309],[0.374892,14.928908],[0.295646,14.444235],[0.429928,13.988733],[0.993046,13.33575],[1.024103,12.851826],[2.177108,12.625018],[2.154474,11.94015],[1.935986,11.64115],[1.447178,11.547719],[1.24347,11.110511],[0.899563,10.997339],[0.023803,11.018682],[-0.438702,11.098341],[-0.761576,10.93693],[-1.203358,11.009819],[-2.940409,10.96269],[-2.963896,10.395335],[-2.827496,9.642461]]]}}, -{"type":"Feature","id":"BGD","properties":{"name":"Bangladesh"},"geometry":{"type":"Polygon","coordinates":[[[92.672721,22.041239],[92.652257,21.324048],[92.303234,21.475485],[92.368554,20.670883],[92.082886,21.192195],[92.025215,21.70157],[91.834891,22.182936],[91.417087,22.765019],[90.496006,22.805017],[90.586957,22.392794],[90.272971,21.836368],[89.847467,22.039146],[89.70205,21.857116],[89.418863,21.966179],[89.031961,22.055708],[88.876312,22.879146],[88.52977,23.631142],[88.69994,24.233715],[88.084422,24.501657],[88.306373,24.866079],[88.931554,25.238692],[88.209789,25.768066],[88.563049,26.446526],[89.355094,26.014407],[89.832481,25.965082],[89.920693,25.26975],[90.872211,25.132601],[91.799596,25.147432],[92.376202,24.976693],[91.915093,24.130414],[91.46773,24.072639],[91.158963,23.503527],[91.706475,22.985264],[91.869928,23.624346],[92.146035,23.627499],[92.672721,22.041239]]]}}, -{"type":"Feature","id":"BGR","properties":{"name":"Bulgaria"},"geometry":{"type":"Polygon","coordinates":[[[22.65715,44.234923],[22.944832,43.823785],[23.332302,43.897011],[24.100679,43.741051],[25.569272,43.688445],[26.065159,43.943494],[27.2424,44.175986],[27.970107,43.812468],[28.558081,43.707462],[28.039095,43.293172],[27.673898,42.577892],[27.99672,42.007359],[27.135739,42.141485],[26.117042,41.826905],[26.106138,41.328899],[25.197201,41.234486],[24.492645,41.583896],[23.692074,41.309081],[22.952377,41.337994],[22.881374,41.999297],[22.380526,42.32026],[22.545012,42.461362],[22.436595,42.580321],[22.604801,42.898519],[22.986019,43.211161],[22.500157,43.642814],[22.410446,44.008063],[22.65715,44.234923]]]}}, -{"type":"Feature","id":"BHS","properties":{"name":"The Bahamas"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-77.53466,23.75975],[-77.78,23.71],[-78.03405,24.28615],[-78.40848,24.57564],[-78.19087,25.2103],[-77.89,25.17],[-77.54,24.34],[-77.53466,23.75975]]],[[[-77.82,26.58],[-78.91,26.42],[-78.98,26.79],[-78.51,26.87],[-77.85,26.84],[-77.82,26.58]]],[[[-77,26.59],[-77.17255,25.87918],[-77.35641,26.00735],[-77.34,26.53],[-77.78802,26.92516],[-77.79,27.04],[-77,26.59]]]]}}, -{"type":"Feature","id":"BIH","properties":{"name":"Bosnia and Herzegovina"},"geometry":{"type":"Polygon","coordinates":[[[19.005486,44.860234],[19.36803,44.863],[19.11761,44.42307],[19.59976,44.03847],[19.454,43.5681],[19.21852,43.52384],[19.03165,43.43253],[18.70648,43.20011],[18.56,42.65],[17.674922,43.028563],[17.297373,43.446341],[16.916156,43.667722],[16.456443,44.04124],[16.23966,44.351143],[15.750026,44.818712],[15.959367,45.233777],[16.318157,45.004127],[16.534939,45.211608],[17.002146,45.233777],[17.861783,45.06774],[18.553214,45.08159],[19.005486,44.860234]]]}}, -{"type":"Feature","id":"BLR","properties":{"name":"Belarus"},"geometry":{"type":"Polygon","coordinates":[[[23.484128,53.912498],[24.450684,53.905702],[25.536354,54.282423],[25.768433,54.846963],[26.588279,55.167176],[26.494331,55.615107],[27.10246,55.783314],[28.176709,56.16913],[29.229513,55.918344],[29.371572,55.670091],[29.896294,55.789463],[30.873909,55.550976],[30.971836,55.081548],[30.757534,54.811771],[31.384472,54.157056],[31.791424,53.974639],[31.731273,53.794029],[32.405599,53.618045],[32.693643,53.351421],[32.304519,53.132726],[31.497644,53.167427],[31.305201,53.073996],[31.540018,52.742052],[31.785998,52.101678],[30.927549,52.042353],[30.619454,51.822806],[30.555117,51.319503],[30.157364,51.416138],[29.254938,51.368234],[28.992835,51.602044],[28.617613,51.427714],[28.241615,51.572227],[27.454066,51.592303],[26.337959,51.832289],[25.327788,51.910656],[24.553106,51.888461],[24.005078,51.617444],[23.527071,51.578454],[23.508002,52.023647],[23.199494,52.486977],[23.799199,52.691099],[23.804935,53.089731],[23.527536,53.470122],[23.484128,53.912498]]]}}, -{"type":"Feature","id":"BLZ","properties":{"name":"Belize"},"geometry":{"type":"Polygon","coordinates":[[[-89.14308,17.808319],[-89.150909,17.955468],[-89.029857,18.001511],[-88.848344,17.883198],[-88.490123,18.486831],[-88.300031,18.499982],[-88.296336,18.353273],[-88.106813,18.348674],[-88.123479,18.076675],[-88.285355,17.644143],[-88.197867,17.489475],[-88.302641,17.131694],[-88.239518,17.036066],[-88.355428,16.530774],[-88.551825,16.265467],[-88.732434,16.233635],[-88.930613,15.887273],[-89.229122,15.886938],[-89.150806,17.015577],[-89.14308,17.808319]]]}}, -{"type":"Feature","id":"BMU","properties":{"name":"Bermuda"},"geometry":{"type":"Polygon","coordinates":[[[-64.7799734332998,32.3072000581802],[-64.7873319183061,32.3039237143428],[-64.7946942710173,32.3032682700388],[-64.8094297981283,32.3098175728414],[-64.8167896352437,32.3058845718466],[-64.8101968029642,32.3022833180511],[-64.7962291465484,32.2934409732427],[-64.7815086336978,32.2868973114514],[-64.7997025513437,32.2796896417328],[-64.8066707691087,32.2747767569465],[-64.8225587873683,32.2669111289395],[-64.8287548840306,32.2669075473817],[-64.8306732143498,32.2583944840235],[-64.8399924854972,32.254782282336],[-64.8566090462354,32.2547740387514],[-64.8682296789446,32.2616393614322],[-64.8628241459563,32.2724481933959],[-64.8748651338951,32.2757120264753],[-64.8717752856644,32.2819371582026],[-64.8671422127295,32.2930760547989],[-64.8559068764437,32.2960321186471],[-64.8597429072279,32.3015842021933],[-64.8439233486717,32.3140553852543],[-64.8350242329311,32.3242161760006],[-64.8338690593672,32.3294587561557],[-64.8520298651164,32.3110911879954],[-64.8635922932573,32.3048469433363],[-64.8686668994079,32.30910745083],[-64.8721354593415,32.3041908606301],[-64.8779667328485,32.3038632800462],[-64.8780046844321,32.2907757831692],[-64.8849776658292,32.2819261366004],[-64.8783230004629,32.2613001418681],[-64.863194968877,32.2465799485801],[-64.8519819555722,32.2485519134663],[-64.842311980074,32.2492123317296],[-64.8388242605209,32.2475773472534],[-64.8334002575532,32.2462714714698],[-64.8256389530584,32.2472637398594],[-64.8205697556026,32.2531698880328],[-64.8105087275579,32.2561208974156],[-64.7900177727338,32.2659446936992],[-64.7745415970416,32.2718413023427],[-64.7644742436426,32.2855931353214],[-64.7551803442276,32.2908326702531],[-64.7423982971436,32.2996734994024],[-64.7206991797682,32.3137542201258],[-64.7117851247134,32.3176823360806],[-64.6962778813133,32.3275029115532],[-64.6768921127452,32.3324095397555],[-64.6567136927777,32.3451776458469],[-64.6532168823499,32.3494356627941],[-64.6605720384429,32.3589423487763],[-64.65125819471,32.3615600906466],[-64.6462011670816,32.36975169749],[-64.6613227512832,32.3763135008721],[-64.6690666074397,32.388444543924],[-64.6834270548595,32.3854968316788],[-64.6954617672714,32.3763221285869],[-64.70438689565,32.3704254760469],[-64.7117569982798,32.368132600249],[-64.7061764744404,32.3600110593559],[-64.700531552697,32.3590601356818],[-64.6940348033967,32.3640708659835],[-64.6895164826082,32.3633598579866],[-64.6864150099255,32.3547797587266],[-64.6824635995504,32.3540628176846],[-64.6835876652835,32.3626447677968],[-64.6801998697415,32.3631199096979],[-64.6672170444687,32.3597751617473],[-64.6598811264978,32.3497625771755],[-64.6737331235384,32.3390281851635],[-64.6887090648183,32.3342439408053],[-64.706732854446,32.3429010723036],[-64.7149301576112,32.3552188753513],[-64.7185967666669,32.3552239212394],[-64.7214189847314,32.3518830231342],[-64.7270616067222,32.3466461715475],[-64.734962460882,32.3442819830499],[-64.7383521549094,32.3407216514918],[-64.7411729976333,32.3311790864627],[-64.7423019216485,32.323311561213],[-64.7462482354281,32.318538611581],[-64.7566773739613,32.3130509130175],[-64.768738200563,32.3088369816572],[-64.7799734332998,32.3072000581802]]]}}, -{"type":"Feature","id":"BOL","properties":{"name":"Bolivia"},"geometry":{"type":"Polygon","coordinates":[[[-62.846468,-22.034985],[-63.986838,-21.993644],[-64.377021,-22.798091],[-64.964892,-22.075862],[-66.273339,-21.83231],[-67.106674,-22.735925],[-67.82818,-22.872919],[-68.219913,-21.494347],[-68.757167,-20.372658],[-68.442225,-19.405068],[-68.966818,-18.981683],[-69.100247,-18.260125],[-69.590424,-17.580012],[-68.959635,-16.500698],[-69.389764,-15.660129],[-69.160347,-15.323974],[-69.339535,-14.953195],[-68.948887,-14.453639],[-68.929224,-13.602684],[-68.88008,-12.899729],[-68.66508,-12.5613],[-69.529678,-10.951734],[-68.786158,-11.03638],[-68.271254,-11.014521],[-68.048192,-10.712059],[-67.173801,-10.306812],[-66.646908,-9.931331],[-65.338435,-9.761988],[-65.444837,-10.511451],[-65.321899,-10.895872],[-65.402281,-11.56627],[-64.316353,-12.461978],[-63.196499,-12.627033],[-62.80306,-13.000653],[-62.127081,-13.198781],[-61.713204,-13.489202],[-61.084121,-13.479384],[-60.503304,-13.775955],[-60.459198,-14.354007],[-60.264326,-14.645979],[-60.251149,-15.077219],[-60.542966,-15.09391],[-60.15839,-16.258284],[-58.24122,-16.299573],[-58.388058,-16.877109],[-58.280804,-17.27171],[-57.734558,-17.552468],[-57.498371,-18.174188],[-57.676009,-18.96184],[-57.949997,-19.400004],[-57.853802,-19.969995],[-58.166392,-20.176701],[-58.183471,-19.868399],[-59.115042,-19.356906],[-60.043565,-19.342747],[-61.786326,-19.633737],[-62.265961,-20.513735],[-62.291179,-21.051635],[-62.685057,-22.249029],[-62.846468,-22.034985]]]}}, -{"type":"Feature","id":"BRA","properties":{"name":"Brazil"},"geometry":{"type":"Polygon","coordinates":[[[-57.625133,-30.216295],[-56.2909,-28.852761],[-55.162286,-27.881915],[-54.490725,-27.474757],[-53.648735,-26.923473],[-53.628349,-26.124865],[-54.13005,-25.547639],[-54.625291,-25.739255],[-54.428946,-25.162185],[-54.293476,-24.5708],[-54.29296,-24.021014],[-54.652834,-23.839578],[-55.027902,-24.001274],[-55.400747,-23.956935],[-55.517639,-23.571998],[-55.610683,-22.655619],[-55.797958,-22.35693],[-56.473317,-22.0863],[-56.88151,-22.282154],[-57.937156,-22.090176],[-57.870674,-20.732688],[-58.166392,-20.176701],[-57.853802,-19.969995],[-57.949997,-19.400004],[-57.676009,-18.96184],[-57.498371,-18.174188],[-57.734558,-17.552468],[-58.280804,-17.27171],[-58.388058,-16.877109],[-58.24122,-16.299573],[-60.15839,-16.258284],[-60.542966,-15.09391],[-60.251149,-15.077219],[-60.264326,-14.645979],[-60.459198,-14.354007],[-60.503304,-13.775955],[-61.084121,-13.479384],[-61.713204,-13.489202],[-62.127081,-13.198781],[-62.80306,-13.000653],[-63.196499,-12.627033],[-64.316353,-12.461978],[-65.402281,-11.56627],[-65.321899,-10.895872],[-65.444837,-10.511451],[-65.338435,-9.761988],[-66.646908,-9.931331],[-67.173801,-10.306812],[-68.048192,-10.712059],[-68.271254,-11.014521],[-68.786158,-11.03638],[-69.529678,-10.951734],[-70.093752,-11.123972],[-70.548686,-11.009147],[-70.481894,-9.490118],[-71.302412,-10.079436],[-72.184891,-10.053598],[-72.563033,-9.520194],[-73.226713,-9.462213],[-73.015383,-9.032833],[-73.571059,-8.424447],[-73.987235,-7.52383],[-73.723401,-7.340999],[-73.724487,-6.918595],[-73.120027,-6.629931],[-73.219711,-6.089189],[-72.964507,-5.741251],[-72.891928,-5.274561],[-71.748406,-4.593983],[-70.928843,-4.401591],[-70.794769,-4.251265],[-69.893635,-4.298187],[-69.444102,-1.556287],[-69.420486,-1.122619],[-69.577065,-0.549992],[-70.020656,-0.185156],[-70.015566,0.541414],[-69.452396,0.706159],[-69.252434,0.602651],[-69.218638,0.985677],[-69.804597,1.089081],[-69.816973,1.714805],[-67.868565,1.692455],[-67.53781,2.037163],[-67.259998,1.719999],[-67.065048,1.130112],[-66.876326,1.253361],[-66.325765,0.724452],[-65.548267,0.789254],[-65.354713,1.095282],[-64.611012,1.328731],[-64.199306,1.492855],[-64.083085,1.916369],[-63.368788,2.2009],[-63.422867,2.411068],[-64.269999,2.497006],[-64.408828,3.126786],[-64.368494,3.79721],[-64.816064,4.056445],[-64.628659,4.148481],[-63.888343,4.02053],[-63.093198,3.770571],[-62.804533,4.006965],[-62.08543,4.162124],[-60.966893,4.536468],[-60.601179,4.918098],[-60.733574,5.200277],[-60.213683,5.244486],[-59.980959,5.014061],[-60.111002,4.574967],[-59.767406,4.423503],[-59.53804,3.958803],[-59.815413,3.606499],[-59.974525,2.755233],[-59.718546,2.24963],[-59.646044,1.786894],[-59.030862,1.317698],[-58.540013,1.268088],[-58.429477,1.463942],[-58.11345,1.507195],[-57.660971,1.682585],[-57.335823,1.948538],[-56.782704,1.863711],[-56.539386,1.899523],[-55.995698,1.817667],[-55.9056,2.021996],[-56.073342,2.220795],[-55.973322,2.510364],[-55.569755,2.421506],[-55.097587,2.523748],[-54.524754,2.311849],[-54.088063,2.105557],[-53.778521,2.376703],[-53.554839,2.334897],[-53.418465,2.053389],[-52.939657,2.124858],[-52.556425,2.504705],[-52.249338,3.241094],[-51.657797,4.156232],[-51.317146,4.203491],[-51.069771,3.650398],[-50.508875,1.901564],[-49.974076,1.736483],[-49.947101,1.04619],[-50.699251,0.222984],[-50.388211,-0.078445],[-48.620567,-0.235489],[-48.584497,-1.237805],[-47.824956,-0.581618],[-46.566584,-0.941028],[-44.905703,-1.55174],[-44.417619,-2.13775],[-44.581589,-2.691308],[-43.418791,-2.38311],[-41.472657,-2.912018],[-39.978665,-2.873054],[-38.500383,-3.700652],[-37.223252,-4.820946],[-36.452937,-5.109404],[-35.597796,-5.149504],[-35.235389,-5.464937],[-34.89603,-6.738193],[-34.729993,-7.343221],[-35.128212,-8.996401],[-35.636967,-9.649282],[-37.046519,-11.040721],[-37.683612,-12.171195],[-38.423877,-13.038119],[-38.673887,-13.057652],[-38.953276,-13.79337],[-38.882298,-15.667054],[-39.161092,-17.208407],[-39.267339,-17.867746],[-39.583521,-18.262296],[-39.760823,-19.599113],[-40.774741,-20.904512],[-40.944756,-21.937317],[-41.754164,-22.370676],[-41.988284,-22.97007],[-43.074704,-22.967693],[-44.647812,-23.351959],[-45.352136,-23.796842],[-46.472093,-24.088969],[-47.648972,-24.885199],[-48.495458,-25.877025],[-48.641005,-26.623698],[-48.474736,-27.175912],[-48.66152,-28.186135],[-48.888457,-28.674115],[-49.587329,-29.224469],[-50.696874,-30.984465],[-51.576226,-31.777698],[-52.256081,-32.24537],[-52.7121,-33.196578],[-53.373662,-33.768378],[-53.650544,-33.202004],[-53.209589,-32.727666],[-53.787952,-32.047243],[-54.572452,-31.494511],[-55.60151,-30.853879],[-55.973245,-30.883076],[-56.976026,-30.109686],[-57.625133,-30.216295]]]}}, -{"type":"Feature","id":"BRN","properties":{"name":"Brunei"},"geometry":{"type":"Polygon","coordinates":[[[114.204017,4.525874],[114.599961,4.900011],[115.45071,5.44773],[115.4057,4.955228],[115.347461,4.316636],[114.869557,4.348314],[114.659596,4.007637],[114.204017,4.525874]]]}}, -{"type":"Feature","id":"BTN","properties":{"name":"Bhutan"},"geometry":{"type":"Polygon","coordinates":[[[91.696657,27.771742],[92.103712,27.452614],[92.033484,26.83831],[91.217513,26.808648],[90.373275,26.875724],[89.744528,26.719403],[88.835643,27.098966],[88.814248,27.299316],[89.47581,28.042759],[90.015829,28.296439],[90.730514,28.064954],[91.258854,28.040614],[91.696657,27.771742]]]}}, -{"type":"Feature","id":"BWA","properties":{"name":"Botswana"},"geometry":{"type":"Polygon","coordinates":[[[25.649163,-18.536026],[25.850391,-18.714413],[26.164791,-19.293086],[27.296505,-20.39152],[27.724747,-20.499059],[27.727228,-20.851802],[28.02137,-21.485975],[28.794656,-21.639454],[29.432188,-22.091313],[28.017236,-22.827754],[27.11941,-23.574323],[26.786407,-24.240691],[26.485753,-24.616327],[25.941652,-24.696373],[25.765849,-25.174845],[25.664666,-25.486816],[25.025171,-25.71967],[24.211267,-25.670216],[23.73357,-25.390129],[23.312097,-25.26869],[22.824271,-25.500459],[22.579532,-25.979448],[22.105969,-26.280256],[21.605896,-26.726534],[20.889609,-26.828543],[20.66647,-26.477453],[20.758609,-25.868136],[20.165726,-24.917962],[19.895768,-24.76779],[19.895458,-21.849157],[20.881134,-21.814327],[20.910641,-18.252219],[21.65504,-18.219146],[23.196858,-17.869038],[23.579006,-18.281261],[24.217365,-17.889347],[24.520705,-17.887125],[25.084443,-17.661816],[25.264226,-17.73654],[25.649163,-18.536026]]]}}, -{"type":"Feature","id":"CAF","properties":{"name":"Central African Republic"},"geometry":{"type":"Polygon","coordinates":[[[15.27946,7.421925],[16.106232,7.497088],[16.290562,7.754307],[16.456185,7.734774],[16.705988,7.508328],[17.96493,7.890914],[18.389555,8.281304],[18.911022,8.630895],[18.81201,8.982915],[19.094008,9.074847],[20.059685,9.012706],[21.000868,9.475985],[21.723822,10.567056],[22.231129,10.971889],[22.864165,11.142395],[22.977544,10.714463],[23.554304,10.089255],[23.55725,9.681218],[23.394779,9.265068],[23.459013,8.954286],[23.805813,8.666319],[24.567369,8.229188],[25.114932,7.825104],[25.124131,7.500085],[25.796648,6.979316],[26.213418,6.546603],[26.465909,5.946717],[27.213409,5.550953],[27.374226,5.233944],[27.044065,5.127853],[26.402761,5.150875],[25.650455,5.256088],[25.278798,5.170408],[25.128833,4.927245],[24.805029,4.897247],[24.410531,5.108784],[23.297214,4.609693],[22.84148,4.710126],[22.704124,4.633051],[22.405124,4.02916],[21.659123,4.224342],[20.927591,4.322786],[20.290679,4.691678],[19.467784,5.031528],[18.932312,4.709506],[18.542982,4.201785],[18.453065,3.504386],[17.8099,3.560196],[17.133042,3.728197],[16.537058,3.198255],[16.012852,2.26764],[15.907381,2.557389],[15.862732,3.013537],[15.405396,3.335301],[15.03622,3.851367],[14.950953,4.210389],[14.478372,4.732605],[14.558936,5.030598],[14.459407,5.451761],[14.53656,6.226959],[14.776545,6.408498],[15.27946,7.421925]]]}}, -{"type":"Feature","id":"CAN","properties":{"name":"Canada"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-63.6645,46.55001],[-62.9393,46.41587],[-62.01208,46.44314],[-62.50391,46.03339],[-62.87433,45.96818],[-64.1428,46.39265],[-64.39261,46.72747],[-64.01486,47.03601],[-63.6645,46.55001]]],[[[-61.806305,49.10506],[-62.29318,49.08717],[-63.58926,49.40069],[-64.51912,49.87304],[-64.17322,49.95718],[-62.85829,49.70641],[-61.835585,49.28855],[-61.806305,49.10506]]],[[[-123.510002,48.510011],[-124.012891,48.370846],[-125.655013,48.825005],[-125.954994,49.179996],[-126.850004,49.53],[-127.029993,49.814996],[-128.059336,49.994959],[-128.444584,50.539138],[-128.358414,50.770648],[-127.308581,50.552574],[-126.695001,50.400903],[-125.755007,50.295018],[-125.415002,49.950001],[-124.920768,49.475275],[-123.922509,49.062484],[-123.510002,48.510011]]],[[[-56.134036,50.68701],[-56.795882,49.812309],[-56.143105,50.150117],[-55.471492,49.935815],[-55.822401,49.587129],[-54.935143,49.313011],[-54.473775,49.556691],[-53.476549,49.249139],[-53.786014,48.516781],[-53.086134,48.687804],[-52.958648,48.157164],[-52.648099,47.535548],[-53.069158,46.655499],[-53.521456,46.618292],[-54.178936,46.807066],[-53.961869,47.625207],[-54.240482,47.752279],[-55.400773,46.884994],[-55.997481,46.91972],[-55.291219,47.389562],[-56.250799,47.632545],[-57.325229,47.572807],[-59.266015,47.603348],[-59.419494,47.899454],[-58.796586,48.251525],[-59.231625,48.523188],[-58.391805,49.125581],[-57.35869,50.718274],[-56.73865,51.287438],[-55.870977,51.632094],[-55.406974,51.588273],[-55.600218,51.317075],[-56.134036,50.68701]]],[[[-132.710008,54.040009],[-131.74999,54.120004],[-132.04948,52.984621],[-131.179043,52.180433],[-131.57783,52.182371],[-132.180428,52.639707],[-132.549992,53.100015],[-133.054611,53.411469],[-133.239664,53.85108],[-133.180004,54.169975],[-132.710008,54.040009]]],[[[-79.26582,62.158675],[-79.65752,61.63308],[-80.09956,61.7181],[-80.36215,62.01649],[-80.315395,62.085565],[-79.92939,62.3856],[-79.52002,62.36371],[-79.26582,62.158675]]],[[[-81.89825,62.7108],[-83.06857,62.15922],[-83.77462,62.18231],[-83.99367,62.4528],[-83.25048,62.91409],[-81.87699,62.90458],[-81.89825,62.7108]]],[[[-85.161308,65.657285],[-84.975764,65.217518],[-84.464012,65.371772],[-83.882626,65.109618],[-82.787577,64.766693],[-81.642014,64.455136],[-81.55344,63.979609],[-80.817361,64.057486],[-80.103451,63.725981],[-80.99102,63.411246],[-82.547178,63.651722],[-83.108798,64.101876],[-84.100417,63.569712],[-85.523405,63.052379],[-85.866769,63.637253],[-87.221983,63.541238],[-86.35276,64.035833],[-86.224886,64.822917],[-85.883848,65.738778],[-85.161308,65.657285]]],[[[-75.86588,67.14886],[-76.98687,67.09873],[-77.2364,67.58809],[-76.81166,68.14856],[-75.89521,68.28721],[-75.1145,68.01036],[-75.10333,67.58202],[-75.21597,67.44425],[-75.86588,67.14886]]],[[[-95.647681,69.10769],[-96.269521,68.75704],[-97.617401,69.06003],[-98.431801,68.9507],[-99.797401,69.40003],[-98.917401,69.71003],[-98.218261,70.14354],[-97.157401,69.86003],[-96.557401,69.68003],[-96.257401,69.49003],[-95.647681,69.10769]]],[[[-90.5471,69.49766],[-90.55151,68.47499],[-89.21515,69.25873],[-88.01966,68.61508],[-88.31749,67.87338],[-87.35017,67.19872],[-86.30607,67.92146],[-85.57664,68.78456],[-85.52197,69.88211],[-84.10081,69.80539],[-82.62258,69.65826],[-81.28043,69.16202],[-81.2202,68.66567],[-81.96436,68.13253],[-81.25928,67.59716],[-81.38653,67.11078],[-83.34456,66.41154],[-84.73542,66.2573],[-85.76943,66.55833],[-86.0676,66.05625],[-87.03143,65.21297],[-87.32324,64.77563],[-88.48296,64.09897],[-89.91444,64.03273],[-90.70398,63.61017],[-90.77004,62.96021],[-91.93342,62.83508],[-93.15698,62.02469],[-94.24153,60.89865],[-94.62931,60.11021],[-94.6846,58.94882],[-93.21502,58.78212],[-92.76462,57.84571],[-92.29703,57.08709],[-90.89769,57.28468],[-89.03953,56.85172],[-88.03978,56.47162],[-87.32421,55.99914],[-86.07121,55.72383],[-85.01181,55.3026],[-83.36055,55.24489],[-82.27285,55.14832],[-82.4362,54.28227],[-82.12502,53.27703],[-81.40075,52.15788],[-79.91289,51.20842],[-79.14301,51.53393],[-78.60191,52.56208],[-79.12421,54.14145],[-79.82958,54.66772],[-78.22874,55.13645],[-77.0956,55.83741],[-76.54137,56.53423],[-76.62319,57.20263],[-77.30226,58.05209],[-78.51688,58.80458],[-77.33676,59.85261],[-77.77272,60.75788],[-78.10687,62.31964],[-77.41067,62.55053],[-75.69621,62.2784],[-74.6682,62.18111],[-73.83988,62.4438],[-72.90853,62.10507],[-71.67708,61.52535],[-71.37369,61.13717],[-69.59042,61.06141],[-69.62033,60.22125],[-69.2879,58.95736],[-68.37455,58.80106],[-67.64976,58.21206],[-66.20178,58.76731],[-65.24517,59.87071],[-64.58352,60.33558],[-63.80475,59.4426],[-62.50236,58.16708],[-61.39655,56.96745],[-61.79866,56.33945],[-60.46853,55.77548],[-59.56962,55.20407],[-57.97508,54.94549],[-57.3332,54.6265],[-56.93689,53.78032],[-56.15811,53.64749],[-55.75632,53.27036],[-55.68338,52.14664],[-56.40916,51.7707],[-57.12691,51.41972],[-58.77482,51.0643],[-60.03309,50.24277],[-61.72366,50.08046],[-63.86251,50.29099],[-65.36331,50.2982],[-66.39905,50.22897],[-67.23631,49.51156],[-68.51114,49.06836],[-69.95362,47.74488],[-71.10458,46.82171],[-70.25522,46.98606],[-68.65,48.3],[-66.55243,49.1331],[-65.05626,49.23278],[-64.17099,48.74248],[-65.11545,48.07085],[-64.79854,46.99297],[-64.47219,46.23849],[-63.17329,45.73902],[-61.52072,45.88377],[-60.51815,47.00793],[-60.4486,46.28264],[-59.80287,45.9204],[-61.03988,45.26525],[-63.25471,44.67014],[-64.24656,44.26553],[-65.36406,43.54523],[-66.1234,43.61867],[-66.16173,44.46512],[-64.42549,45.29204],[-66.02605,45.25931],[-67.13741,45.13753],[-67.79134,45.70281],[-67.79046,47.06636],[-68.23444,47.35486],[-68.905,47.185],[-69.237216,47.447781],[-69.99997,46.69307],[-70.305,45.915],[-70.66,45.46],[-71.08482,45.30524],[-71.405,45.255],[-71.50506,45.0082],[-73.34783,45.00738],[-74.867,45.00048],[-75.31821,44.81645],[-76.375,44.09631],[-76.5,44.018459],[-76.820034,43.628784],[-77.737885,43.629056],[-78.72028,43.625089],[-79.171674,43.466339],[-79.01,43.27],[-78.92,42.965],[-78.939362,42.863611],[-80.247448,42.3662],[-81.277747,42.209026],[-82.439278,41.675105],[-82.690089,41.675105],[-83.02981,41.832796],[-83.142,41.975681],[-83.12,42.08],[-82.9,42.43],[-82.43,42.98],[-82.137642,43.571088],[-82.337763,44.44],[-82.550925,45.347517],[-83.592851,45.816894],[-83.469551,45.994686],[-83.616131,46.116927],[-83.890765,46.116927],[-84.091851,46.275419],[-84.14212,46.512226],[-84.3367,46.40877],[-84.6049,46.4396],[-84.543749,46.538684],[-84.779238,46.637102],[-84.87608,46.900083],[-85.652363,47.220219],[-86.461991,47.553338],[-87.439793,47.94],[-88.378114,48.302918],[-89.272917,48.019808],[-89.6,48.01],[-90.83,48.27],[-91.64,48.14],[-92.61,48.45],[-93.63087,48.60926],[-94.32914,48.67074],[-94.64,48.84],[-94.81758,49.38905],[-95.15609,49.38425],[-95.15907,49],[-97.22872,49.0007],[-100.65,49],[-104.04826,48.99986],[-107.05,49],[-110.05,49],[-113,49],[-116.04818,49],[-117.03121,49],[-120,49],[-122.84,49],[-122.97421,49.002538],[-124.91024,49.98456],[-125.62461,50.41656],[-127.43561,50.83061],[-127.99276,51.71583],[-127.85032,52.32961],[-129.12979,52.75538],[-129.30523,53.56159],[-130.51497,54.28757],[-130.53611,54.80278],[-129.98,55.285],[-130.00778,55.91583],[-131.70781,56.55212],[-132.73042,57.69289],[-133.35556,58.41028],[-134.27111,58.86111],[-134.945,59.27056],[-135.47583,59.78778],[-136.47972,59.46389],[-137.4525,58.905],[-138.34089,59.56211],[-139.039,60],[-140.013,60.27682],[-140.99778,60.30639],[-140.9925,66.00003],[-140.986,69.712],[-139.12052,69.47102],[-137.54636,68.99002],[-136.50358,68.89804],[-135.62576,69.31512],[-134.41464,69.62743],[-132.92925,69.50534],[-131.43136,69.94451],[-129.79471,70.19369],[-129.10773,69.77927],[-128.36156,70.01286],[-128.13817,70.48384],[-127.44712,70.37721],[-125.75632,69.48058],[-124.42483,70.1584],[-124.28968,69.39969],[-123.06108,69.56372],[-122.6835,69.85553],[-121.47226,69.79778],[-119.94288,69.37786],[-117.60268,69.01128],[-116.22643,68.84151],[-115.2469,68.90591],[-113.89794,68.3989],[-115.30489,67.90261],[-113.49727,67.68815],[-110.798,67.80612],[-109.94619,67.98104],[-108.8802,67.38144],[-107.79239,67.88736],[-108.81299,68.31164],[-108.16721,68.65392],[-106.95,68.7],[-106.15,68.8],[-105.34282,68.56122],[-104.33791,68.018],[-103.22115,68.09775],[-101.45433,67.64689],[-99.90195,67.80566],[-98.4432,67.78165],[-98.5586,68.40394],[-97.66948,68.57864],[-96.11991,68.23939],[-96.12588,67.29338],[-95.48943,68.0907],[-94.685,68.06383],[-94.23282,69.06903],[-95.30408,69.68571],[-96.47131,70.08976],[-96.39115,71.19482],[-95.2088,71.92053],[-93.88997,71.76015],[-92.87818,71.31869],[-91.51964,70.19129],[-92.40692,69.69997],[-90.5471,69.49766]]],[[[-114.16717,73.12145],[-114.66634,72.65277],[-112.44102,72.9554],[-111.05039,72.4504],[-109.92035,72.96113],[-109.00654,72.63335],[-108.18835,71.65089],[-107.68599,72.06548],[-108.39639,73.08953],[-107.51645,73.23598],[-106.52259,73.07601],[-105.40246,72.67259],[-104.77484,71.6984],[-104.46476,70.99297],[-102.78537,70.49776],[-100.98078,70.02432],[-101.08929,69.58447],[-102.73116,69.50402],[-102.09329,69.11962],[-102.43024,68.75282],[-104.24,68.91],[-105.96,69.18],[-107.12254,69.11922],[-109,68.78],[-111.534149,68.630059],[-113.3132,68.53554],[-113.85496,69.00744],[-115.22,69.28],[-116.10794,69.16821],[-117.34,69.96],[-116.67473,70.06655],[-115.13112,70.2373],[-113.72141,70.19237],[-112.4161,70.36638],[-114.35,70.6],[-116.48684,70.52045],[-117.9048,70.54056],[-118.43238,70.9092],[-116.11311,71.30918],[-117.65568,71.2952],[-119.40199,71.55859],[-118.56267,72.30785],[-117.86642,72.70594],[-115.18909,73.31459],[-114.16717,73.12145]]],[[[-104.5,73.42],[-105.38,72.76],[-106.94,73.46],[-106.6,73.6],[-105.26,73.64],[-104.5,73.42]]],[[[-76.34,73.102685],[-76.251404,72.826385],[-77.314438,72.855545],[-78.39167,72.876656],[-79.486252,72.742203],[-79.775833,72.802902],[-80.876099,73.333183],[-80.833885,73.693184],[-80.353058,73.75972],[-78.064438,73.651932],[-76.34,73.102685]]],[[[-86.562179,73.157447],[-85.774371,72.534126],[-84.850112,73.340278],[-82.31559,73.750951],[-80.600088,72.716544],[-80.748942,72.061907],[-78.770639,72.352173],[-77.824624,72.749617],[-75.605845,72.243678],[-74.228616,71.767144],[-74.099141,71.33084],[-72.242226,71.556925],[-71.200015,70.920013],[-68.786054,70.525024],[-67.91497,70.121948],[-66.969033,69.186087],[-68.805123,68.720198],[-66.449866,68.067163],[-64.862314,67.847539],[-63.424934,66.928473],[-61.851981,66.862121],[-62.163177,66.160251],[-63.918444,64.998669],[-65.14886,65.426033],[-66.721219,66.388041],[-68.015016,66.262726],[-68.141287,65.689789],[-67.089646,65.108455],[-65.73208,64.648406],[-65.320168,64.382737],[-64.669406,63.392927],[-65.013804,62.674185],[-66.275045,62.945099],[-68.783186,63.74567],[-67.369681,62.883966],[-66.328297,62.280075],[-66.165568,61.930897],[-68.877367,62.330149],[-71.023437,62.910708],[-72.235379,63.397836],[-71.886278,63.679989],[-73.378306,64.193963],[-74.834419,64.679076],[-74.818503,64.389093],[-77.70998,64.229542],[-78.555949,64.572906],[-77.897281,65.309192],[-76.018274,65.326969],[-73.959795,65.454765],[-74.293883,65.811771],[-73.944912,66.310578],[-72.651167,67.284576],[-72.92606,67.726926],[-73.311618,68.069437],[-74.843307,68.554627],[-76.869101,68.894736],[-76.228649,69.147769],[-77.28737,69.76954],[-78.168634,69.826488],[-78.957242,70.16688],[-79.492455,69.871808],[-81.305471,69.743185],[-84.944706,69.966634],[-87.060003,70.260001],[-88.681713,70.410741],[-89.51342,70.762038],[-88.467721,71.218186],[-89.888151,71.222552],[-90.20516,72.235074],[-89.436577,73.129464],[-88.408242,73.537889],[-85.826151,73.803816],[-86.562179,73.157447]]],[[[-100.35642,73.84389],[-99.16387,73.63339],[-97.38,73.76],[-97.12,73.47],[-98.05359,72.99052],[-96.54,72.56],[-96.72,71.66],[-98.35966,71.27285],[-99.32286,71.35639],[-100.01482,71.73827],[-102.5,72.51],[-102.48,72.83],[-100.43836,72.70588],[-101.54,73.36],[-100.35642,73.84389]]],[[[-93.196296,72.771992],[-94.269047,72.024596],[-95.409856,72.061881],[-96.033745,72.940277],[-96.018268,73.43743],[-95.495793,73.862417],[-94.503658,74.134907],[-92.420012,74.100025],[-90.509793,73.856732],[-92.003965,72.966244],[-93.196296,72.771992]]],[[[-120.46,71.383602],[-123.09219,70.90164],[-123.62,71.34],[-125.928949,71.868688],[-125.5,72.292261],[-124.80729,73.02256],[-123.94,73.68],[-124.91775,74.29275],[-121.53788,74.44893],[-120.10978,74.24135],[-117.55564,74.18577],[-116.58442,73.89607],[-115.51081,73.47519],[-116.76794,73.22292],[-119.22,72.52],[-120.46,71.82],[-120.46,71.383602]]],[[[-93.612756,74.979997],[-94.156909,74.592347],[-95.608681,74.666864],[-96.820932,74.927623],[-96.288587,75.377828],[-94.85082,75.647218],[-93.977747,75.29649],[-93.612756,74.979997]]],[[[-98.5,76.72],[-97.735585,76.25656],[-97.704415,75.74344],[-98.16,75],[-99.80874,74.89744],[-100.88366,75.05736],[-100.86292,75.64075],[-102.50209,75.5638],[-102.56552,76.3366],[-101.48973,76.30537],[-99.98349,76.64634],[-98.57699,76.58859],[-98.5,76.72]]],[[[-108.21141,76.20168],[-107.81943,75.84552],[-106.92893,76.01282],[-105.881,75.9694],[-105.70498,75.47951],[-106.31347,75.00527],[-109.7,74.85],[-112.22307,74.41696],[-113.74381,74.39427],[-113.87135,74.72029],[-111.79421,75.1625],[-116.31221,75.04343],[-117.7104,75.2222],[-116.34602,76.19903],[-115.40487,76.47887],[-112.59056,76.14134],[-110.81422,75.54919],[-109.0671,75.47321],[-110.49726,76.42982],[-109.5811,76.79417],[-108.54859,76.67832],[-108.21141,76.20168]]],[[[-94.684086,77.097878],[-93.573921,76.776296],[-91.605023,76.778518],[-90.741846,76.449597],[-90.969661,76.074013],[-89.822238,75.847774],[-89.187083,75.610166],[-87.838276,75.566189],[-86.379192,75.482421],[-84.789625,75.699204],[-82.753445,75.784315],[-81.128531,75.713983],[-80.057511,75.336849],[-79.833933,74.923127],[-80.457771,74.657304],[-81.948843,74.442459],[-83.228894,74.564028],[-86.097452,74.410032],[-88.15035,74.392307],[-89.764722,74.515555],[-92.422441,74.837758],[-92.768285,75.38682],[-92.889906,75.882655],[-93.893824,76.319244],[-95.962457,76.441381],[-97.121379,76.751078],[-96.745123,77.161389],[-94.684086,77.097878]]],[[[-116.198587,77.645287],[-116.335813,76.876962],[-117.106051,76.530032],[-118.040412,76.481172],[-119.899318,76.053213],[-121.499995,75.900019],[-122.854924,76.116543],[-122.854925,76.116543],[-121.157535,76.864508],[-119.103939,77.51222],[-117.570131,77.498319],[-116.198587,77.645287]]],[[[-93.840003,77.519997],[-94.295608,77.491343],[-96.169654,77.555111],[-96.436304,77.834629],[-94.422577,77.820005],[-93.720656,77.634331],[-93.840003,77.519997]]],[[[-110.186938,77.697015],[-112.051191,77.409229],[-113.534279,77.732207],[-112.724587,78.05105],[-111.264443,78.152956],[-109.854452,77.996325],[-110.186938,77.697015]]],[[[-109.663146,78.601973],[-110.881314,78.40692],[-112.542091,78.407902],[-112.525891,78.550555],[-111.50001,78.849994],[-110.963661,78.804441],[-109.663146,78.601973]]],[[[-95.830295,78.056941],[-97.309843,77.850597],[-98.124289,78.082857],[-98.552868,78.458105],[-98.631984,78.87193],[-97.337231,78.831984],[-96.754399,78.765813],[-95.559278,78.418315],[-95.830295,78.056941]]],[[[-100.060192,78.324754],[-99.670939,77.907545],[-101.30394,78.018985],[-102.949809,78.343229],[-105.176133,78.380332],[-104.210429,78.67742],[-105.41958,78.918336],[-105.492289,79.301594],[-103.529282,79.165349],[-100.825158,78.800462],[-100.060192,78.324754]]],[[[-87.02,79.66],[-85.81435,79.3369],[-87.18756,79.0393],[-89.03535,78.28723],[-90.80436,78.21533],[-92.87669,78.34333],[-93.95116,78.75099],[-93.93574,79.11373],[-93.14524,79.3801],[-94.974,79.37248],[-96.07614,79.70502],[-96.70972,80.15777],[-96.01644,80.60233],[-95.32345,80.90729],[-94.29843,80.97727],[-94.73542,81.20646],[-92.40984,81.25739],[-91.13289,80.72345],[-89.45,80.509322],[-87.81,80.32],[-87.02,79.66]]],[[[-68.5,83.106322],[-65.82735,83.02801],[-63.68,82.9],[-61.85,82.6286],[-61.89388,82.36165],[-64.334,81.92775],[-66.75342,81.72527],[-67.65755,81.50141],[-65.48031,81.50657],[-67.84,80.9],[-69.4697,80.61683],[-71.18,79.8],[-73.2428,79.63415],[-73.88,79.430162],[-76.90773,79.32309],[-75.52924,79.19766],[-76.22046,79.01907],[-75.39345,78.52581],[-76.34354,78.18296],[-77.88851,77.89991],[-78.36269,77.50859],[-79.75951,77.20968],[-79.61965,76.98336],[-77.91089,77.022045],[-77.88911,76.777955],[-80.56125,76.17812],[-83.17439,76.45403],[-86.11184,76.29901],[-87.6,76.42],[-89.49068,76.47239],[-89.6161,76.95213],[-87.76739,77.17833],[-88.26,77.9],[-87.65,77.970222],[-84.97634,77.53873],[-86.34,78.18],[-87.96192,78.37181],[-87.15198,78.75867],[-85.37868,78.9969],[-85.09495,79.34543],[-86.50734,79.73624],[-86.93179,80.25145],[-84.19844,80.20836],[-83.408696,80.1],[-81.84823,80.46442],[-84.1,80.58],[-87.59895,80.51627],[-89.36663,80.85569],[-90.2,81.26],[-91.36786,81.5531],[-91.58702,81.89429],[-90.1,82.085],[-88.93227,82.11751],[-86.97024,82.27961],[-85.5,82.652273],[-84.260005,82.6],[-83.18,82.32],[-82.42,82.86],[-81.1,83.02],[-79.30664,83.13056],[-76.25,83.172059],[-75.71878,83.06404],[-72.83153,83.23324],[-70.665765,83.169781],[-68.5,83.106322]]]]}}, -{"type":"Feature","id":"CHE","properties":{"name":"Switzerland"},"geometry":{"type":"Polygon","coordinates":[[[9.594226,47.525058],[9.632932,47.347601],[9.47997,47.10281],[9.932448,46.920728],[10.442701,46.893546],[10.363378,46.483571],[9.922837,46.314899],[9.182882,46.440215],[8.966306,46.036932],[8.489952,46.005151],[8.31663,46.163642],[7.755992,45.82449],[7.273851,45.776948],[6.843593,45.991147],[6.5001,46.429673],[6.022609,46.27299],[6.037389,46.725779],[6.768714,47.287708],[6.736571,47.541801],[7.192202,47.449766],[7.466759,47.620582],[8.317301,47.61358],[8.522612,47.830828],[9.594226,47.525058]]]}}, -{"type":"Feature","id":"CHL","properties":{"name":"Chile"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-68.63401,-52.63637],[-68.63335,-54.8695],[-67.56244,-54.87001],[-66.95992,-54.89681],[-67.29103,-55.30124],[-68.14863,-55.61183],[-68.639991,-55.580018],[-69.2321,-55.49906],[-69.95809,-55.19843],[-71.00568,-55.05383],[-72.2639,-54.49514],[-73.2852,-53.95752],[-74.66253,-52.83749],[-73.8381,-53.04743],[-72.43418,-53.7154],[-71.10773,-54.07433],[-70.59178,-53.61583],[-70.26748,-52.93123],[-69.34565,-52.5183],[-68.63401,-52.63637]]],[[[-68.219913,-21.494347],[-67.82818,-22.872919],[-67.106674,-22.735925],[-66.985234,-22.986349],[-67.328443,-24.025303],[-68.417653,-24.518555],[-68.386001,-26.185016],[-68.5948,-26.506909],[-68.295542,-26.89934],[-69.001235,-27.521214],[-69.65613,-28.459141],[-70.01355,-29.367923],[-69.919008,-30.336339],[-70.535069,-31.36501],[-70.074399,-33.09121],[-69.814777,-33.273886],[-69.817309,-34.193571],[-70.388049,-35.169688],[-70.364769,-36.005089],[-71.121881,-36.658124],[-71.118625,-37.576827],[-70.814664,-38.552995],[-71.413517,-38.916022],[-71.680761,-39.808164],[-71.915734,-40.832339],[-71.746804,-42.051386],[-72.148898,-42.254888],[-71.915424,-43.408565],[-71.464056,-43.787611],[-71.793623,-44.207172],[-71.329801,-44.407522],[-71.222779,-44.784243],[-71.659316,-44.973689],[-71.552009,-45.560733],[-71.917258,-46.884838],[-72.447355,-47.738533],[-72.331161,-48.244238],[-72.648247,-48.878618],[-73.415436,-49.318436],[-73.328051,-50.378785],[-72.975747,-50.74145],[-72.309974,-50.67701],[-72.329404,-51.425956],[-71.914804,-52.009022],[-69.498362,-52.142761],[-68.571545,-52.299444],[-69.461284,-52.291951],[-69.94278,-52.537931],[-70.845102,-52.899201],[-71.006332,-53.833252],[-71.429795,-53.856455],[-72.557943,-53.53141],[-73.702757,-52.835069],[-73.702757,-52.83507],[-74.946763,-52.262754],[-75.260026,-51.629355],[-74.976632,-51.043396],[-75.479754,-50.378372],[-75.608015,-48.673773],[-75.18277,-47.711919],[-74.126581,-46.939253],[-75.644395,-46.647643],[-74.692154,-45.763976],[-74.351709,-44.103044],[-73.240356,-44.454961],[-72.717804,-42.383356],[-73.3889,-42.117532],[-73.701336,-43.365776],[-74.331943,-43.224958],[-74.017957,-41.794813],[-73.677099,-39.942213],[-73.217593,-39.258689],[-73.505559,-38.282883],[-73.588061,-37.156285],[-73.166717,-37.12378],[-72.553137,-35.50884],[-71.861732,-33.909093],[-71.43845,-32.418899],[-71.668721,-30.920645],[-71.370083,-30.095682],[-71.489894,-28.861442],[-70.905124,-27.64038],[-70.724954,-25.705924],[-70.403966,-23.628997],[-70.091246,-21.393319],[-70.16442,-19.756468],[-70.372572,-18.347975],[-69.858444,-18.092694],[-69.590424,-17.580012],[-69.100247,-18.260125],[-68.966818,-18.981683],[-68.442225,-19.405068],[-68.757167,-20.372658],[-68.219913,-21.494347]]]]}}, -{"type":"Feature","id":"CHN","properties":{"name":"China"},"geometry":{"type":"MultiPolygon","coordinates":[[[[110.339188,18.678395],[109.47521,18.197701],[108.655208,18.507682],[108.626217,19.367888],[109.119056,19.821039],[110.211599,20.101254],[110.786551,20.077534],[111.010051,19.69593],[110.570647,19.255879],[110.339188,18.678395]]],[[[127.657407,49.76027],[129.397818,49.4406],[130.582293,48.729687],[130.987282,47.790132],[132.506672,47.78897],[133.373596,48.183442],[135.026311,48.47823],[134.500814,47.57844],[134.112362,47.212467],[133.769644,46.116927],[133.097127,45.144066],[131.883454,45.321162],[131.025212,44.967953],[131.288555,44.11152],[131.144688,42.92999],[130.633866,42.903015],[130.640016,42.395009],[129.994267,42.985387],[129.596669,42.424982],[128.052215,41.994285],[128.208433,41.466772],[127.343783,41.503152],[126.869083,41.816569],[126.182045,41.107336],[125.079942,40.569824],[124.265625,39.928493],[122.86757,39.637788],[122.131388,39.170452],[121.054554,38.897471],[121.585995,39.360854],[121.376757,39.750261],[122.168595,40.422443],[121.640359,40.94639],[120.768629,40.593388],[119.639602,39.898056],[119.023464,39.252333],[118.042749,39.204274],[117.532702,38.737636],[118.059699,38.061476],[118.87815,37.897325],[118.911636,37.448464],[119.702802,37.156389],[120.823457,37.870428],[121.711259,37.481123],[122.357937,37.454484],[122.519995,36.930614],[121.104164,36.651329],[120.637009,36.11144],[119.664562,35.609791],[119.151208,34.909859],[120.227525,34.360332],[120.620369,33.376723],[121.229014,32.460319],[121.908146,31.692174],[121.891919,30.949352],[121.264257,30.676267],[121.503519,30.142915],[122.092114,29.83252],[121.938428,29.018022],[121.684439,28.225513],[121.125661,28.135673],[120.395473,27.053207],[119.585497,25.740781],[118.656871,24.547391],[117.281606,23.624501],[115.890735,22.782873],[114.763827,22.668074],[114.152547,22.22376],[113.80678,22.54834],[113.241078,22.051367],[111.843592,21.550494],[110.785466,21.397144],[110.444039,20.341033],[109.889861,20.282457],[109.627655,21.008227],[109.864488,21.395051],[108.522813,21.715212],[108.05018,21.55238],[107.04342,21.811899],[106.567273,22.218205],[106.725403,22.794268],[105.811247,22.976892],[105.329209,23.352063],[104.476858,22.81915],[103.504515,22.703757],[102.706992,22.708795],[102.170436,22.464753],[101.652018,22.318199],[101.80312,21.174367],[101.270026,21.201652],[101.180005,21.436573],[101.150033,21.849984],[100.416538,21.558839],[99.983489,21.742937],[99.240899,22.118314],[99.531992,22.949039],[98.898749,23.142722],[98.660262,24.063286],[97.60472,23.897405],[97.724609,25.083637],[98.671838,25.918703],[98.712094,26.743536],[98.68269,27.508812],[98.246231,27.747221],[97.911988,28.335945],[97.327114,28.261583],[96.248833,28.411031],[96.586591,28.83098],[96.117679,29.452802],[95.404802,29.031717],[94.56599,29.277438],[93.413348,28.640629],[92.503119,27.896876],[91.696657,27.771742],[91.258854,28.040614],[90.730514,28.064954],[90.015829,28.296439],[89.47581,28.042759],[88.814248,27.299316],[88.730326,28.086865],[88.120441,27.876542],[86.954517,27.974262],[85.82332,28.203576],[85.011638,28.642774],[84.23458,28.839894],[83.898993,29.320226],[83.337115,29.463732],[82.327513,30.115268],[81.525804,30.422717],[81.111256,30.183481],[79.721367,30.882715],[78.738894,31.515906],[78.458446,32.618164],[79.176129,32.48378],[79.208892,32.994395],[78.811086,33.506198],[78.912269,34.321936],[77.837451,35.49401],[76.192848,35.898403],[75.896897,36.666806],[75.158028,37.133031],[74.980002,37.41999],[74.829986,37.990007],[74.864816,38.378846],[74.257514,38.606507],[73.928852,38.505815],[73.675379,39.431237],[73.960013,39.660008],[73.822244,39.893973],[74.776862,40.366425],[75.467828,40.562072],[76.526368,40.427946],[76.904484,41.066486],[78.187197,41.185316],[78.543661,41.582243],[80.11943,42.123941],[80.25999,42.349999],[80.18015,42.920068],[80.866206,43.180362],[79.966106,44.917517],[81.947071,45.317027],[82.458926,45.53965],[83.180484,47.330031],[85.16429,47.000956],[85.720484,47.452969],[85.768233,48.455751],[86.598776,48.549182],[87.35997,49.214981],[87.751264,49.297198],[88.013832,48.599463],[88.854298,48.069082],[90.280826,47.693549],[90.970809,46.888146],[90.585768,45.719716],[90.94554,45.286073],[92.133891,45.115076],[93.480734,44.975472],[94.688929,44.352332],[95.306875,44.241331],[95.762455,43.319449],[96.349396,42.725635],[97.451757,42.74889],[99.515817,42.524691],[100.845866,42.663804],[101.83304,42.514873],[103.312278,41.907468],[104.522282,41.908347],[104.964994,41.59741],[106.129316,42.134328],[107.744773,42.481516],[109.243596,42.519446],[110.412103,42.871234],[111.129682,43.406834],[111.829588,43.743118],[111.667737,44.073176],[111.348377,44.457442],[111.873306,45.102079],[112.436062,45.011646],[113.463907,44.808893],[114.460332,45.339817],[115.985096,45.727235],[116.717868,46.388202],[117.421701,46.672733],[118.874326,46.805412],[119.66327,46.69268],[119.772824,47.048059],[118.866574,47.74706],[118.064143,48.06673],[117.295507,47.697709],[116.308953,47.85341],[115.742837,47.726545],[115.485282,48.135383],[116.191802,49.134598],[116.678801,49.888531],[117.879244,49.510983],[119.288461,50.142883],[119.279366,50.582908],[120.18205,51.643566],[120.738191,51.964115],[120.725789,52.516226],[120.177089,52.753886],[121.003085,53.251401],[122.245748,53.431726],[123.571507,53.458804],[125.068211,53.161045],[125.946349,52.792799],[126.564399,51.784255],[126.939157,51.353894],[127.287456,50.739797],[127.657407,49.76027]]]]}}, -{"type":"Feature","id":"CIV","properties":{"name":"Ivory Coast"},"geometry":{"type":"Polygon","coordinates":[[[-2.856125,4.994476],[-3.311084,4.984296],[-4.00882,5.179813],[-4.649917,5.168264],[-5.834496,4.993701],[-6.528769,4.705088],[-7.518941,4.338288],[-7.712159,4.364566],[-7.635368,5.188159],[-7.539715,5.313345],[-7.570153,5.707352],[-7.993693,6.12619],[-8.311348,6.193033],[-8.60288,6.467564],[-8.385452,6.911801],[-8.485446,7.395208],[-8.439298,7.686043],[-8.280703,7.68718],[-8.221792,8.123329],[-8.299049,8.316444],[-8.203499,8.455453],[-7.8321,8.575704],[-8.079114,9.376224],[-8.309616,9.789532],[-8.229337,10.12902],[-8.029944,10.206535],[-7.89959,10.297382],[-7.622759,10.147236],[-6.850507,10.138994],[-6.666461,10.430811],[-6.493965,10.411303],[-6.205223,10.524061],[-6.050452,10.096361],[-5.816926,10.222555],[-5.404342,10.370737],[-4.954653,10.152714],[-4.779884,9.821985],[-4.330247,9.610835],[-3.980449,9.862344],[-3.511899,9.900326],[-2.827496,9.642461],[-2.56219,8.219628],[-2.983585,7.379705],[-3.24437,6.250472],[-2.810701,5.389051],[-2.856125,4.994476]]]}}, -{"type":"Feature","id":"CMR","properties":{"name":"Cameroon"},"geometry":{"type":"Polygon","coordinates":[[[13.075822,2.267097],[12.951334,2.321616],[12.35938,2.192812],[11.751665,2.326758],[11.276449,2.261051],[9.649158,2.283866],[9.795196,3.073404],[9.404367,3.734527],[8.948116,3.904129],[8.744924,4.352215],[8.488816,4.495617],[8.500288,4.771983],[8.757533,5.479666],[9.233163,6.444491],[9.522706,6.453482],[10.118277,7.03877],[10.497375,7.055358],[11.058788,6.644427],[11.745774,6.981383],[11.839309,7.397042],[12.063946,7.799808],[12.218872,8.305824],[12.753672,8.717763],[12.955468,9.417772],[13.1676,9.640626],[13.308676,10.160362],[13.57295,10.798566],[14.415379,11.572369],[14.468192,11.904752],[14.577178,12.085361],[14.181336,12.483657],[14.213531,12.802035],[14.495787,12.859396],[14.893386,12.219048],[14.960152,11.555574],[14.923565,10.891325],[15.467873,9.982337],[14.909354,9.992129],[14.627201,9.920919],[14.171466,10.021378],[13.954218,9.549495],[14.544467,8.965861],[14.979996,8.796104],[15.120866,8.38215],[15.436092,7.692812],[15.27946,7.421925],[14.776545,6.408498],[14.53656,6.226959],[14.459407,5.451761],[14.558936,5.030598],[14.478372,4.732605],[14.950953,4.210389],[15.03622,3.851367],[15.405396,3.335301],[15.862732,3.013537],[15.907381,2.557389],[16.012852,2.26764],[15.940919,1.727673],[15.146342,1.964015],[14.337813,2.227875],[13.075822,2.267097]]]}}, -{"type":"Feature","id":"COD","properties":{"name":"Democratic Republic of the Congo"},"geometry":{"type":"Polygon","coordinates":[[[30.83386,3.509166],[30.773347,2.339883],[31.174149,2.204465],[30.85267,1.849396],[30.468508,1.583805],[30.086154,1.062313],[29.875779,0.59738],[29.819503,-0.20531],[29.587838,-0.587406],[29.579466,-1.341313],[29.291887,-1.620056],[29.254835,-2.21511],[29.117479,-2.292211],[29.024926,-2.839258],[29.276384,-3.293907],[29.339998,-4.499983],[29.519987,-5.419979],[29.419993,-5.939999],[29.620032,-6.520015],[30.199997,-7.079981],[30.740015,-8.340007],[30.346086,-8.238257],[29.002912,-8.407032],[28.734867,-8.526559],[28.449871,-9.164918],[28.673682,-9.605925],[28.49607,-10.789884],[28.372253,-11.793647],[28.642417,-11.971569],[29.341548,-12.360744],[29.616001,-12.178895],[29.699614,-13.257227],[28.934286,-13.248958],[28.523562,-12.698604],[28.155109,-12.272481],[27.388799,-12.132747],[27.16442,-11.608748],[26.553088,-11.92444],[25.75231,-11.784965],[25.418118,-11.330936],[24.78317,-11.238694],[24.314516,-11.262826],[24.257155,-10.951993],[23.912215,-10.926826],[23.456791,-10.867863],[22.837345,-11.017622],[22.402798,-10.993075],[22.155268,-11.084801],[22.208753,-9.894796],[21.875182,-9.523708],[21.801801,-8.908707],[21.949131,-8.305901],[21.746456,-7.920085],[21.728111,-7.290872],[20.514748,-7.299606],[20.601823,-6.939318],[20.091622,-6.94309],[20.037723,-7.116361],[19.417502,-7.155429],[19.166613,-7.738184],[19.016752,-7.988246],[18.464176,-7.847014],[18.134222,-7.987678],[17.47297,-8.068551],[17.089996,-7.545689],[16.860191,-7.222298],[16.57318,-6.622645],[16.326528,-5.87747],[13.375597,-5.864241],[13.024869,-5.984389],[12.735171,-5.965682],[12.322432,-6.100092],[12.182337,-5.789931],[12.436688,-5.684304],[12.468004,-5.248362],[12.631612,-4.991271],[12.995517,-4.781103],[13.25824,-4.882957],[13.600235,-4.500138],[14.144956,-4.510009],[14.209035,-4.793092],[14.582604,-4.970239],[15.170992,-4.343507],[15.75354,-3.855165],[16.00629,-3.535133],[15.972803,-2.712392],[16.407092,-1.740927],[16.865307,-1.225816],[17.523716,-0.74383],[17.638645,-0.424832],[17.663553,-0.058084],[17.82654,0.288923],[17.774192,0.855659],[17.898835,1.741832],[18.094276,2.365722],[18.393792,2.900443],[18.453065,3.504386],[18.542982,4.201785],[18.932312,4.709506],[19.467784,5.031528],[20.290679,4.691678],[20.927591,4.322786],[21.659123,4.224342],[22.405124,4.02916],[22.704124,4.633051],[22.84148,4.710126],[23.297214,4.609693],[24.410531,5.108784],[24.805029,4.897247],[25.128833,4.927245],[25.278798,5.170408],[25.650455,5.256088],[26.402761,5.150875],[27.044065,5.127853],[27.374226,5.233944],[27.979977,4.408413],[28.428994,4.287155],[28.696678,4.455077],[29.159078,4.389267],[29.715995,4.600805],[29.9535,4.173699],[30.83386,3.509166]]]}}, -{"type":"Feature","id":"COG","properties":{"name":"Republic of the Congo"},"geometry":{"type":"Polygon","coordinates":[[[12.995517,-4.781103],[12.62076,-4.438023],[12.318608,-4.60623],[11.914963,-5.037987],[11.093773,-3.978827],[11.855122,-3.426871],[11.478039,-2.765619],[11.820964,-2.514161],[12.495703,-2.391688],[12.575284,-1.948511],[13.109619,-2.42874],[13.992407,-2.470805],[14.29921,-1.998276],[14.425456,-1.333407],[14.316418,-0.552627],[13.843321,0.038758],[14.276266,1.19693],[14.026669,1.395677],[13.282631,1.314184],[13.003114,1.830896],[13.075822,2.267097],[14.337813,2.227875],[15.146342,1.964015],[15.940919,1.727673],[16.012852,2.26764],[16.537058,3.198255],[17.133042,3.728197],[17.8099,3.560196],[18.453065,3.504386],[18.393792,2.900443],[18.094276,2.365722],[17.898835,1.741832],[17.774192,0.855659],[17.82654,0.288923],[17.663553,-0.058084],[17.638645,-0.424832],[17.523716,-0.74383],[16.865307,-1.225816],[16.407092,-1.740927],[15.972803,-2.712392],[16.00629,-3.535133],[15.75354,-3.855165],[15.170992,-4.343507],[14.582604,-4.970239],[14.209035,-4.793092],[14.144956,-4.510009],[13.600235,-4.500138],[13.25824,-4.882957],[12.995517,-4.781103]]]}}, -{"type":"Feature","id":"COL","properties":{"name":"Colombia"},"geometry":{"type":"Polygon","coordinates":[[[-75.373223,-0.152032],[-75.801466,0.084801],[-76.292314,0.416047],[-76.57638,0.256936],[-77.424984,0.395687],[-77.668613,0.825893],[-77.855061,0.809925],[-78.855259,1.380924],[-78.990935,1.69137],[-78.617831,1.766404],[-78.662118,2.267355],[-78.42761,2.629556],[-77.931543,2.696606],[-77.510431,3.325017],[-77.12769,3.849636],[-77.496272,4.087606],[-77.307601,4.667984],[-77.533221,5.582812],[-77.318815,5.845354],[-77.476661,6.691116],[-77.881571,7.223771],[-77.753414,7.70984],[-77.431108,7.638061],[-77.242566,7.935278],[-77.474723,8.524286],[-77.353361,8.670505],[-76.836674,8.638749],[-76.086384,9.336821],[-75.6746,9.443248],[-75.664704,9.774003],[-75.480426,10.61899],[-74.906895,11.083045],[-74.276753,11.102036],[-74.197223,11.310473],[-73.414764,11.227015],[-72.627835,11.731972],[-72.238195,11.95555],[-71.75409,12.437303],[-71.399822,12.376041],[-71.137461,12.112982],[-71.331584,11.776284],[-71.973922,11.608672],[-72.227575,11.108702],[-72.614658,10.821975],[-72.905286,10.450344],[-73.027604,9.73677],[-73.304952,9.152],[-72.78873,9.085027],[-72.660495,8.625288],[-72.439862,8.405275],[-72.360901,8.002638],[-72.479679,7.632506],[-72.444487,7.423785],[-72.198352,7.340431],[-71.960176,6.991615],[-70.674234,7.087785],[-70.093313,6.960376],[-69.38948,6.099861],[-68.985319,6.206805],[-68.265052,6.153268],[-67.695087,6.267318],[-67.34144,6.095468],[-67.521532,5.55687],[-67.744697,5.221129],[-67.823012,4.503937],[-67.621836,3.839482],[-67.337564,3.542342],[-67.303173,3.318454],[-67.809938,2.820655],[-67.447092,2.600281],[-67.181294,2.250638],[-66.876326,1.253361],[-67.065048,1.130112],[-67.259998,1.719999],[-67.53781,2.037163],[-67.868565,1.692455],[-69.816973,1.714805],[-69.804597,1.089081],[-69.218638,0.985677],[-69.252434,0.602651],[-69.452396,0.706159],[-70.015566,0.541414],[-70.020656,-0.185156],[-69.577065,-0.549992],[-69.420486,-1.122619],[-69.444102,-1.556287],[-69.893635,-4.298187],[-70.394044,-3.766591],[-70.692682,-3.742872],[-70.047709,-2.725156],[-70.813476,-2.256865],[-71.413646,-2.342802],[-71.774761,-2.16979],[-72.325787,-2.434218],[-73.070392,-2.308954],[-73.659504,-1.260491],[-74.122395,-1.002833],[-74.441601,-0.53082],[-75.106625,-0.057205],[-75.373223,-0.152032]]]}}, -{"type":"Feature","id":"CRI","properties":{"name":"Costa Rica"},"geometry":{"type":"Polygon","coordinates":[[[-82.965783,8.225028],[-83.508437,8.446927],[-83.711474,8.656836],[-83.596313,8.830443],[-83.632642,9.051386],[-83.909886,9.290803],[-84.303402,9.487354],[-84.647644,9.615537],[-84.713351,9.908052],[-84.97566,10.086723],[-84.911375,9.795992],[-85.110923,9.55704],[-85.339488,9.834542],[-85.660787,9.933347],[-85.797445,10.134886],[-85.791709,10.439337],[-85.659314,10.754331],[-85.941725,10.895278],[-85.71254,11.088445],[-85.561852,11.217119],[-84.903003,10.952303],[-84.673069,11.082657],[-84.355931,10.999226],[-84.190179,10.79345],[-83.895054,10.726839],[-83.655612,10.938764],[-83.40232,10.395438],[-83.015677,9.992982],[-82.546196,9.566135],[-82.932891,9.476812],[-82.927155,9.07433],[-82.719183,8.925709],[-82.868657,8.807266],[-82.829771,8.626295],[-82.913176,8.423517],[-82.965783,8.225028]]]}}, -{"type":"Feature","id":"CUB","properties":{"name":"Cuba"},"geometry":{"type":"Polygon","coordinates":[[[-82.268151,23.188611],[-81.404457,23.117271],[-80.618769,23.10598],[-79.679524,22.765303],[-79.281486,22.399202],[-78.347434,22.512166],[-77.993296,22.277194],[-77.146422,21.657851],[-76.523825,21.20682],[-76.19462,21.220565],[-75.598222,21.016624],[-75.67106,20.735091],[-74.933896,20.693905],[-74.178025,20.284628],[-74.296648,20.050379],[-74.961595,19.923435],[-75.63468,19.873774],[-76.323656,19.952891],[-77.755481,19.855481],[-77.085108,20.413354],[-77.492655,20.673105],[-78.137292,20.739949],[-78.482827,21.028613],[-78.719867,21.598114],[-79.285,21.559175],[-80.217475,21.827324],[-80.517535,22.037079],[-81.820943,22.192057],[-82.169992,22.387109],[-81.795002,22.636965],[-82.775898,22.68815],[-83.494459,22.168518],[-83.9088,22.154565],[-84.052151,21.910575],[-84.54703,21.801228],[-84.974911,21.896028],[-84.447062,22.20495],[-84.230357,22.565755],[-83.77824,22.788118],[-83.267548,22.983042],[-82.510436,23.078747],[-82.268151,23.188611]]]}}, -{"type":"Feature","id":"-99","properties":{"name":"Northern Cyprus"},"geometry":{"type":"Polygon","coordinates":[[[32.73178,35.140026],[32.802474,35.145504],[32.946961,35.386703],[33.667227,35.373216],[34.576474,35.671596],[33.900804,35.245756],[33.973617,35.058506],[33.86644,35.093595],[33.675392,35.017863],[33.525685,35.038688],[33.475817,35.000345],[33.455922,35.101424],[33.383833,35.162712],[33.190977,35.173125],[32.919572,35.087833],[32.73178,35.140026]]]}}, -{"type":"Feature","id":"CYP","properties":{"name":"Cyprus"},"geometry":{"type":"Polygon","coordinates":[[[33.973617,35.058506],[34.004881,34.978098],[32.979827,34.571869],[32.490296,34.701655],[32.256667,35.103232],[32.73178,35.140026],[32.919572,35.087833],[33.190977,35.173125],[33.383833,35.162712],[33.455922,35.101424],[33.475817,35.000345],[33.525685,35.038688],[33.675392,35.017863],[33.86644,35.093595],[33.973617,35.058506]]]}}, -{"type":"Feature","id":"CZE","properties":{"name":"Czech Republic"},"geometry":{"type":"Polygon","coordinates":[[[16.960288,48.596982],[16.499283,48.785808],[16.029647,48.733899],[15.253416,49.039074],[14.901447,48.964402],[14.338898,48.555305],[13.595946,48.877172],[13.031329,49.307068],[12.521024,49.547415],[12.415191,49.969121],[12.240111,50.266338],[12.966837,50.484076],[13.338132,50.733234],[14.056228,50.926918],[14.307013,51.117268],[14.570718,51.002339],[15.016996,51.106674],[15.490972,50.78473],[16.238627,50.697733],[16.176253,50.422607],[16.719476,50.215747],[16.868769,50.473974],[17.554567,50.362146],[17.649445,50.049038],[18.392914,49.988629],[18.853144,49.49623],[18.554971,49.495015],[18.399994,49.315001],[18.170498,49.271515],[18.104973,49.043983],[17.913512,48.996493],[17.886485,48.903475],[17.545007,48.800019],[17.101985,48.816969],[16.960288,48.596982]]]}}, -{"type":"Feature","id":"DEU","properties":{"name":"Germany"},"geometry":{"type":"Polygon","coordinates":[[[9.921906,54.983104],[9.93958,54.596642],[10.950112,54.363607],[10.939467,54.008693],[11.956252,54.196486],[12.51844,54.470371],[13.647467,54.075511],[14.119686,53.757029],[14.353315,53.248171],[14.074521,52.981263],[14.4376,52.62485],[14.685026,52.089947],[14.607098,51.745188],[15.016996,51.106674],[14.570718,51.002339],[14.307013,51.117268],[14.056228,50.926918],[13.338132,50.733234],[12.966837,50.484076],[12.240111,50.266338],[12.415191,49.969121],[12.521024,49.547415],[13.031329,49.307068],[13.595946,48.877172],[13.243357,48.416115],[12.884103,48.289146],[13.025851,47.637584],[12.932627,47.467646],[12.62076,47.672388],[12.141357,47.703083],[11.426414,47.523766],[10.544504,47.566399],[10.402084,47.302488],[9.896068,47.580197],[9.594226,47.525058],[8.522612,47.830828],[8.317301,47.61358],[7.466759,47.620582],[7.593676,48.333019],[8.099279,49.017784],[6.65823,49.201958],[6.18632,49.463803],[6.242751,49.902226],[6.043073,50.128052],[6.156658,50.803721],[5.988658,51.851616],[6.589397,51.852029],[6.84287,52.22844],[7.092053,53.144043],[6.90514,53.482162],[7.100425,53.693932],[7.936239,53.748296],[8.121706,53.527792],[8.800734,54.020786],[8.572118,54.395646],[8.526229,54.962744],[9.282049,54.830865],[9.921906,54.983104]]]}}, -{"type":"Feature","id":"DJI","properties":{"name":"Djibouti"},"geometry":{"type":"Polygon","coordinates":[[[43.081226,12.699639],[43.317852,12.390148],[43.286381,11.974928],[42.715874,11.735641],[43.145305,11.46204],[42.776852,10.926879],[42.55493,11.10511],[42.31414,11.0342],[41.75557,11.05091],[41.73959,11.35511],[41.66176,11.6312],[42,12.1],[42.35156,12.54223],[42.779642,12.455416],[43.081226,12.699639]]]}}, -{"type":"Feature","id":"DNK","properties":{"name":"Denmark"},"geometry":{"type":"MultiPolygon","coordinates":[[[[12.690006,55.609991],[12.089991,54.800015],[11.043543,55.364864],[10.903914,55.779955],[12.370904,56.111407],[12.690006,55.609991]]],[[[10.912182,56.458621],[10.667804,56.081383],[10.369993,56.190007],[9.649985,55.469999],[9.921906,54.983104],[9.282049,54.830865],[8.526229,54.962744],[8.120311,55.517723],[8.089977,56.540012],[8.256582,56.809969],[8.543438,57.110003],[9.424469,57.172066],[9.775559,57.447941],[10.580006,57.730017],[10.546106,57.215733],[10.25,56.890016],[10.369993,56.609982],[10.912182,56.458621]]]]}}, -{"type":"Feature","id":"DOM","properties":{"name":"Dominican Republic"},"geometry":{"type":"Polygon","coordinates":[[[-71.712361,19.714456],[-71.587304,19.884911],[-70.806706,19.880286],[-70.214365,19.622885],[-69.950815,19.648],[-69.76925,19.293267],[-69.222126,19.313214],[-69.254346,19.015196],[-68.809412,18.979074],[-68.317943,18.612198],[-68.689316,18.205142],[-69.164946,18.422648],[-69.623988,18.380713],[-69.952934,18.428307],[-70.133233,18.245915],[-70.517137,18.184291],[-70.669298,18.426886],[-70.99995,18.283329],[-71.40021,17.598564],[-71.657662,17.757573],[-71.708305,18.044997],[-71.687738,18.31666],[-71.945112,18.6169],[-71.701303,18.785417],[-71.624873,19.169838],[-71.712361,19.714456]]]}}, -{"type":"Feature","id":"DZA","properties":{"name":"Algeria"},"geometry":{"type":"Polygon","coordinates":[[[11.999506,23.471668],[8.572893,21.565661],[5.677566,19.601207],[4.267419,19.155265],[3.158133,19.057364],[3.146661,19.693579],[2.683588,19.85623],[2.060991,20.142233],[1.823228,20.610809],[-1.550055,22.792666],[-4.923337,24.974574],[-8.6844,27.395744],[-8.665124,27.589479],[-8.66559,27.656426],[-8.674116,28.841289],[-7.059228,29.579228],[-6.060632,29.7317],[-5.242129,30.000443],[-4.859646,30.501188],[-3.690441,30.896952],[-3.647498,31.637294],[-3.06898,31.724498],[-2.616605,32.094346],[-1.307899,32.262889],[-1.124551,32.651522],[-1.388049,32.864015],[-1.733455,33.919713],[-1.792986,34.527919],[-2.169914,35.168396],[-1.208603,35.714849],[-0.127454,35.888662],[0.503877,36.301273],[1.466919,36.605647],[3.161699,36.783905],[4.815758,36.865037],[5.32012,36.716519],[6.26182,37.110655],[7.330385,37.118381],[7.737078,36.885708],[8.420964,36.946427],[8.217824,36.433177],[8.376368,35.479876],[8.140981,34.655146],[7.524482,34.097376],[7.612642,33.344115],[8.430473,32.748337],[8.439103,32.506285],[9.055603,32.102692],[9.48214,30.307556],[9.805634,29.424638],[9.859998,28.95999],[9.683885,28.144174],[9.756128,27.688259],[9.629056,27.140953],[9.716286,26.512206],[9.319411,26.094325],[9.910693,25.365455],[9.948261,24.936954],[10.303847,24.379313],[10.771364,24.562532],[11.560669,24.097909],[11.999506,23.471668]]]}}, -{"type":"Feature","id":"ECU","properties":{"name":"Ecuador"},"geometry":{"type":"Polygon","coordinates":[[[-80.302561,-3.404856],[-79.770293,-2.657512],[-79.986559,-2.220794],[-80.368784,-2.685159],[-80.967765,-2.246943],[-80.764806,-1.965048],[-80.933659,-1.057455],[-80.58337,-0.906663],[-80.399325,-0.283703],[-80.020898,0.36034],[-80.09061,0.768429],[-79.542762,0.982938],[-78.855259,1.380924],[-77.855061,0.809925],[-77.668613,0.825893],[-77.424984,0.395687],[-76.57638,0.256936],[-76.292314,0.416047],[-75.801466,0.084801],[-75.373223,-0.152032],[-75.233723,-0.911417],[-75.544996,-1.56161],[-76.635394,-2.608678],[-77.837905,-3.003021],[-78.450684,-3.873097],[-78.639897,-4.547784],[-79.205289,-4.959129],[-79.624979,-4.454198],[-80.028908,-4.346091],[-80.442242,-4.425724],[-80.469295,-4.059287],[-80.184015,-3.821162],[-80.302561,-3.404856]]]}}, -{"type":"Feature","id":"EGY","properties":{"name":"Egypt"},"geometry":{"type":"Polygon","coordinates":[[[34.9226,29.50133],[34.64174,29.09942],[34.42655,28.34399],[34.15451,27.8233],[33.92136,27.6487],[33.58811,27.97136],[33.13676,28.41765],[32.42323,29.85108],[32.32046,29.76043],[32.73482,28.70523],[33.34876,27.69989],[34.10455,26.14227],[34.47387,25.59856],[34.79507,25.03375],[35.69241,23.92671],[35.49372,23.75237],[35.52598,23.10244],[36.69069,22.20485],[36.86623,22],[32.9,22],[29.02,22],[25,22],[25,25.6825],[25,29.238655],[24.70007,30.04419],[24.95762,30.6616],[24.80287,31.08929],[25.16482,31.56915],[26.49533,31.58568],[27.45762,31.32126],[28.45048,31.02577],[28.91353,30.87005],[29.68342,31.18686],[30.09503,31.4734],[30.97693,31.55586],[31.68796,31.4296],[31.96041,30.9336],[32.19247,31.26034],[32.99392,31.02407],[33.7734,30.96746],[34.26544,31.21936],[34.9226,29.50133]]]}}, -{"type":"Feature","id":"ERI","properties":{"name":"Eritrea"},"geometry":{"type":"Polygon","coordinates":[[[42.35156,12.54223],[42.00975,12.86582],[41.59856,13.45209],[41.155194,13.77332],[40.8966,14.11864],[40.026219,14.519579],[39.34061,14.53155],[39.0994,14.74064],[38.51295,14.50547],[37.90607,14.95943],[37.59377,14.2131],[36.42951,14.42211],[36.323189,14.822481],[36.75386,16.291874],[36.85253,16.95655],[37.16747,17.26314],[37.904,17.42754],[38.41009,17.998307],[38.990623,16.840626],[39.26611,15.922723],[39.814294,15.435647],[41.179275,14.49108],[41.734952,13.921037],[42.276831,13.343992],[42.589576,13.000421],[43.081226,12.699639],[42.779642,12.455416],[42.35156,12.54223]]]}}, -{"type":"Feature","id":"ESP","properties":{"name":"Spain"},"geometry":{"type":"Polygon","coordinates":[[[-9.034818,41.880571],[-8.984433,42.592775],[-9.392884,43.026625],[-7.97819,43.748338],[-6.754492,43.567909],[-5.411886,43.57424],[-4.347843,43.403449],[-3.517532,43.455901],[-1.901351,43.422802],[-1.502771,43.034014],[0.338047,42.579546],[0.701591,42.795734],[1.826793,42.343385],[2.985999,42.473015],[3.039484,41.89212],[2.091842,41.226089],[0.810525,41.014732],[0.721331,40.678318],[0.106692,40.123934],[-0.278711,39.309978],[0.111291,38.738514],[-0.467124,38.292366],[-0.683389,37.642354],[-1.438382,37.443064],[-2.146453,36.674144],[-3.415781,36.6589],[-4.368901,36.677839],[-4.995219,36.324708],[-5.37716,35.94685],[-5.866432,36.029817],[-6.236694,36.367677],[-6.520191,36.942913],[-7.453726,37.097788],[-7.537105,37.428904],[-7.166508,37.803894],[-7.029281,38.075764],[-7.374092,38.373059],[-7.098037,39.030073],[-7.498632,39.629571],[-7.066592,39.711892],[-7.026413,40.184524],[-6.86402,40.330872],[-6.851127,41.111083],[-6.389088,41.381815],[-6.668606,41.883387],[-7.251309,41.918346],[-7.422513,41.792075],[-8.013175,41.790886],[-8.263857,42.280469],[-8.671946,42.134689],[-9.034818,41.880571]]]}}, -{"type":"Feature","id":"EST","properties":{"name":"Estonia"},"geometry":{"type":"Polygon","coordinates":[[[24.312863,57.793424],[24.428928,58.383413],[24.061198,58.257375],[23.42656,58.612753],[23.339795,59.18724],[24.604214,59.465854],[25.864189,59.61109],[26.949136,59.445803],[27.981114,59.475388],[28.131699,59.300825],[27.420166,58.724581],[27.716686,57.791899],[27.288185,57.474528],[26.463532,57.476389],[25.60281,57.847529],[25.164594,57.970157],[24.312863,57.793424]]]}}, -{"type":"Feature","id":"ETH","properties":{"name":"Ethiopia"},"geometry":{"type":"Polygon","coordinates":[[[37.90607,14.95943],[38.51295,14.50547],[39.0994,14.74064],[39.34061,14.53155],[40.02625,14.51959],[40.8966,14.11864],[41.1552,13.77333],[41.59856,13.45209],[42.00975,12.86582],[42.35156,12.54223],[42,12.1],[41.66176,11.6312],[41.73959,11.35511],[41.75557,11.05091],[42.31414,11.0342],[42.55493,11.10511],[42.776852,10.926879],[42.55876,10.57258],[42.92812,10.02194],[43.29699,9.54048],[43.67875,9.18358],[46.94834,7.99688],[47.78942,8.003],[44.9636,5.00162],[43.66087,4.95755],[42.76967,4.25259],[42.12861,4.23413],[41.855083,3.918912],[41.1718,3.91909],[40.76848,4.25702],[39.85494,3.83879],[39.559384,3.42206],[38.89251,3.50074],[38.67114,3.61607],[38.43697,3.58851],[38.120915,3.598605],[36.855093,4.447864],[36.159079,4.447864],[35.817448,4.776966],[35.817448,5.338232],[35.298007,5.506],[34.70702,6.59422],[34.25032,6.82607],[34.0751,7.22595],[33.56829,7.71334],[32.95418,7.78497],[33.2948,8.35458],[33.8255,8.37916],[33.97498,8.68456],[33.96162,9.58358],[34.25745,10.63009],[34.73115,10.91017],[34.83163,11.31896],[35.26049,12.08286],[35.86363,12.57828],[36.27022,13.56333],[36.42951,14.42211],[37.59377,14.2131],[37.90607,14.95943]]]}}, -{"type":"Feature","id":"FIN","properties":{"name":"Finland"},"geometry":{"type":"Polygon","coordinates":[[[28.59193,69.064777],[28.445944,68.364613],[29.977426,67.698297],[29.054589,66.944286],[30.21765,65.80598],[29.54443,64.948672],[30.444685,64.204453],[30.035872,63.552814],[31.516092,62.867687],[31.139991,62.357693],[30.211107,61.780028],[28.069998,60.503517],[26.255173,60.423961],[24.496624,60.057316],[22.869695,59.846373],[22.290764,60.391921],[21.322244,60.72017],[21.544866,61.705329],[21.059211,62.607393],[21.536029,63.189735],[22.442744,63.81781],[24.730512,64.902344],[25.398068,65.111427],[25.294043,65.534346],[23.903379,66.006927],[23.56588,66.396051],[23.539473,67.936009],[21.978535,68.616846],[20.645593,69.106247],[21.244936,69.370443],[22.356238,68.841741],[23.66205,68.891247],[24.735679,68.649557],[25.689213,69.092114],[26.179622,69.825299],[27.732292,70.164193],[29.015573,69.766491],[28.59193,69.064777]]]}}, -{"type":"Feature","id":"FJI","properties":{"name":"Fiji"},"geometry":{"type":"MultiPolygon","coordinates":[[[[178.3736,-17.33992],[178.71806,-17.62846],[178.55271,-18.15059],[177.93266,-18.28799],[177.38146,-18.16432],[177.28504,-17.72465],[177.67087,-17.38114],[178.12557,-17.50481],[178.3736,-17.33992]]],[[[179.364143,-16.801354],[178.725059,-17.012042],[178.596839,-16.63915],[179.096609,-16.433984],[179.413509,-16.379054],[180,-16.067133],[180,-16.555217],[179.364143,-16.801354]]],[[[-179.917369,-16.501783],[-180,-16.555217],[-180,-16.067133],[-179.79332,-16.020882],[-179.917369,-16.501783]]]]}}, -{"type":"Feature","id":"FLK","properties":{"name":"Falkland Islands"},"geometry":{"type":"Polygon","coordinates":[[[-61.2,-51.85],[-60,-51.25],[-59.15,-51.5],[-58.55,-51.1],[-57.75,-51.55],[-58.05,-51.9],[-59.4,-52.2],[-59.85,-51.85],[-60.7,-52.3],[-61.2,-51.85]]]}}, -{"type":"Feature","id":"FRA","properties":{"name":"France"},"geometry":{"type":"MultiPolygon","coordinates":[[[[9.560016,42.152492],[9.229752,41.380007],[8.775723,41.583612],[8.544213,42.256517],[8.746009,42.628122],[9.390001,43.009985],[9.560016,42.152492]]],[[[3.588184,50.378992],[4.286023,49.907497],[4.799222,49.985373],[5.674052,49.529484],[5.897759,49.442667],[6.18632,49.463803],[6.65823,49.201958],[8.099279,49.017784],[7.593676,48.333019],[7.466759,47.620582],[7.192202,47.449766],[6.736571,47.541801],[6.768714,47.287708],[6.037389,46.725779],[6.022609,46.27299],[6.5001,46.429673],[6.843593,45.991147],[6.802355,45.70858],[7.096652,45.333099],[6.749955,45.028518],[7.007562,44.254767],[7.549596,44.127901],[7.435185,43.693845],[6.529245,43.128892],[4.556963,43.399651],[3.100411,43.075201],[2.985999,42.473015],[1.826793,42.343385],[0.701591,42.795734],[0.338047,42.579546],[-1.502771,43.034014],[-1.901351,43.422802],[-1.384225,44.02261],[-1.193798,46.014918],[-2.225724,47.064363],[-2.963276,47.570327],[-4.491555,47.954954],[-4.59235,48.68416],[-3.295814,48.901692],[-1.616511,48.644421],[-1.933494,49.776342],[-0.989469,49.347376],[1.338761,50.127173],[1.639001,50.946606],[2.513573,51.148506],[2.658422,50.796848],[3.123252,50.780363],[3.588184,50.378992]]]]}}, -{"type":"Feature","id":"GAB","properties":{"name":"Gabon"},"geometry":{"type":"Polygon","coordinates":[[[11.093773,-3.978827],[10.066135,-2.969483],[9.405245,-2.144313],[8.797996,-1.111301],[8.830087,-0.779074],[9.04842,-0.459351],[9.291351,0.268666],[9.492889,1.01012],[9.830284,1.067894],[11.285079,1.057662],[11.276449,2.261051],[11.751665,2.326758],[12.35938,2.192812],[12.951334,2.321616],[13.075822,2.267097],[13.003114,1.830896],[13.282631,1.314184],[14.026669,1.395677],[14.276266,1.19693],[13.843321,0.038758],[14.316418,-0.552627],[14.425456,-1.333407],[14.29921,-1.998276],[13.992407,-2.470805],[13.109619,-2.42874],[12.575284,-1.948511],[12.495703,-2.391688],[11.820964,-2.514161],[11.478039,-2.765619],[11.855122,-3.426871],[11.093773,-3.978827]]]}}, -{"type":"Feature","id":"GBR","properties":{"name":"United Kingdom"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-5.661949,54.554603],[-6.197885,53.867565],[-6.95373,54.073702],[-7.572168,54.059956],[-7.366031,54.595841],[-7.572168,55.131622],[-6.733847,55.17286],[-5.661949,54.554603]]],[[[-3.005005,58.635],[-4.073828,57.553025],[-3.055002,57.690019],[-1.959281,57.6848],[-2.219988,56.870017],[-3.119003,55.973793],[-2.085009,55.909998],[-2.005676,55.804903],[-1.114991,54.624986],[-0.430485,54.464376],[0.184981,53.325014],[0.469977,52.929999],[1.681531,52.73952],[1.559988,52.099998],[1.050562,51.806761],[1.449865,51.289428],[0.550334,50.765739],[-0.787517,50.774989],[-2.489998,50.500019],[-2.956274,50.69688],[-3.617448,50.228356],[-4.542508,50.341837],[-5.245023,49.96],[-5.776567,50.159678],[-4.30999,51.210001],[-3.414851,51.426009],[-3.422719,51.426848],[-4.984367,51.593466],[-5.267296,51.9914],[-4.222347,52.301356],[-4.770013,52.840005],[-4.579999,53.495004],[-3.093831,53.404547],[-3.09208,53.404441],[-2.945009,53.985],[-3.614701,54.600937],[-3.630005,54.615013],[-4.844169,54.790971],[-5.082527,55.061601],[-4.719112,55.508473],[-5.047981,55.783986],[-5.586398,55.311146],[-5.644999,56.275015],[-6.149981,56.78501],[-5.786825,57.818848],[-5.009999,58.630013],[-4.211495,58.550845],[-3.005005,58.635]]]]}}, -{"type":"Feature","id":"GEO","properties":{"name":"Georgia"},"geometry":{"type":"Polygon","coordinates":[[[41.554084,41.535656],[41.703171,41.962943],[41.45347,42.645123],[40.875469,43.013628],[40.321394,43.128634],[39.955009,43.434998],[40.076965,43.553104],[40.922185,43.382159],[42.394395,43.220308],[43.756017,42.740828],[43.9312,42.554974],[44.537623,42.711993],[45.470279,42.502781],[45.77641,42.092444],[46.404951,41.860675],[46.145432,41.722802],[46.637908,41.181673],[46.501637,41.064445],[45.962601,41.123873],[45.217426,41.411452],[44.97248,41.248129],[43.582746,41.092143],[42.619549,41.583173],[41.554084,41.535656]]]}}, -{"type":"Feature","id":"GHA","properties":{"name":"Ghana"},"geometry":{"type":"Polygon","coordinates":[[[1.060122,5.928837],[-0.507638,5.343473],[-1.063625,5.000548],[-1.964707,4.710462],[-2.856125,4.994476],[-2.810701,5.389051],[-3.24437,6.250472],[-2.983585,7.379705],[-2.56219,8.219628],[-2.827496,9.642461],[-2.963896,10.395335],[-2.940409,10.96269],[-1.203358,11.009819],[-0.761576,10.93693],[-0.438702,11.098341],[0.023803,11.018682],[-0.049785,10.706918],[0.36758,10.191213],[0.365901,9.465004],[0.461192,8.677223],[0.712029,8.312465],[0.490957,7.411744],[0.570384,6.914359],[0.836931,6.279979],[1.060122,5.928837]]]}}, -{"type":"Feature","id":"GIN","properties":{"name":"Guinea"},"geometry":{"type":"Polygon","coordinates":[[[-8.439298,7.686043],[-8.722124,7.711674],[-8.926065,7.309037],[-9.208786,7.313921],[-9.403348,7.526905],[-9.33728,7.928534],[-9.755342,8.541055],[-10.016567,8.428504],[-10.230094,8.406206],[-10.505477,8.348896],[-10.494315,8.715541],[-10.65477,8.977178],[-10.622395,9.26791],[-10.839152,9.688246],[-11.117481,10.045873],[-11.917277,10.046984],[-12.150338,9.858572],[-12.425929,9.835834],[-12.596719,9.620188],[-12.711958,9.342712],[-13.24655,8.903049],[-13.685154,9.494744],[-14.074045,9.886167],[-14.330076,10.01572],[-14.579699,10.214467],[-14.693232,10.656301],[-14.839554,10.876572],[-15.130311,11.040412],[-14.685687,11.527824],[-14.382192,11.509272],[-14.121406,11.677117],[-13.9008,11.678719],[-13.743161,11.811269],[-13.828272,12.142644],[-13.718744,12.247186],[-13.700476,12.586183],[-13.217818,12.575874],[-12.499051,12.33209],[-12.278599,12.35444],[-12.203565,12.465648],[-11.658301,12.386583],[-11.513943,12.442988],[-11.456169,12.076834],[-11.297574,12.077971],[-11.036556,12.211245],[-10.87083,12.177887],[-10.593224,11.923975],[-10.165214,11.844084],[-9.890993,12.060479],[-9.567912,12.194243],[-9.327616,12.334286],[-9.127474,12.30806],[-8.905265,12.088358],[-8.786099,11.812561],[-8.376305,11.393646],[-8.581305,11.136246],[-8.620321,10.810891],[-8.407311,10.909257],[-8.282357,10.792597],[-8.335377,10.494812],[-8.029944,10.206535],[-8.229337,10.12902],[-8.309616,9.789532],[-8.079114,9.376224],[-7.8321,8.575704],[-8.203499,8.455453],[-8.299049,8.316444],[-8.221792,8.123329],[-8.280703,7.68718],[-8.439298,7.686043]]]}}, -{"type":"Feature","id":"GMB","properties":{"name":"Gambia"},"geometry":{"type":"Polygon","coordinates":[[[-16.841525,13.151394],[-16.713729,13.594959],[-15.624596,13.623587],[-15.39877,13.860369],[-15.081735,13.876492],[-14.687031,13.630357],[-14.376714,13.62568],[-14.046992,13.794068],[-13.844963,13.505042],[-14.277702,13.280585],[-14.712197,13.298207],[-15.141163,13.509512],[-15.511813,13.27857],[-15.691001,13.270353],[-15.931296,13.130284],[-16.841525,13.151394]]]}}, -{"type":"Feature","id":"GNB","properties":{"name":"Guinea Bissau"},"geometry":{"type":"Polygon","coordinates":[[[-15.130311,11.040412],[-15.66418,11.458474],[-16.085214,11.524594],[-16.314787,11.806515],[-16.308947,11.958702],[-16.613838,12.170911],[-16.677452,12.384852],[-16.147717,12.547762],[-15.816574,12.515567],[-15.548477,12.62817],[-13.700476,12.586183],[-13.718744,12.247186],[-13.828272,12.142644],[-13.743161,11.811269],[-13.9008,11.678719],[-14.121406,11.677117],[-14.382192,11.509272],[-14.685687,11.527824],[-15.130311,11.040412]]]}}, -{"type":"Feature","id":"GNQ","properties":{"name":"Equatorial Guinea"},"geometry":{"type":"Polygon","coordinates":[[[9.492889,1.01012],[9.305613,1.160911],[9.649158,2.283866],[11.276449,2.261051],[11.285079,1.057662],[9.830284,1.067894],[9.492889,1.01012]]]}}, -{"type":"Feature","id":"GRC","properties":{"name":"Greece"},"geometry":{"type":"MultiPolygon","coordinates":[[[[23.69998,35.705004],[24.246665,35.368022],[25.025015,35.424996],[25.769208,35.354018],[25.745023,35.179998],[26.290003,35.29999],[26.164998,35.004995],[24.724982,34.919988],[24.735007,35.084991],[23.514978,35.279992],[23.69998,35.705004]]],[[[26.604196,41.562115],[26.294602,40.936261],[26.056942,40.824123],[25.447677,40.852545],[24.925848,40.947062],[23.714811,40.687129],[24.407999,40.124993],[23.899968,39.962006],[23.342999,39.960998],[22.813988,40.476005],[22.626299,40.256561],[22.849748,39.659311],[23.350027,39.190011],[22.973099,38.970903],[23.530016,38.510001],[24.025025,38.219993],[24.040011,37.655015],[23.115003,37.920011],[23.409972,37.409991],[22.774972,37.30501],[23.154225,36.422506],[22.490028,36.41],[21.670026,36.844986],[21.295011,37.644989],[21.120034,38.310323],[20.730032,38.769985],[20.217712,39.340235],[20.150016,39.624998],[20.615,40.110007],[20.674997,40.435],[20.99999,40.580004],[21.02004,40.842727],[21.674161,40.931275],[22.055378,41.149866],[22.597308,41.130487],[22.76177,41.3048],[22.952377,41.337994],[23.692074,41.309081],[24.492645,41.583896],[25.197201,41.234486],[26.106138,41.328899],[26.117042,41.826905],[26.604196,41.562115]]]]}}, -{"type":"Feature","id":"GRL","properties":{"name":"Greenland"},"geometry":{"type":"Polygon","coordinates":[[[-46.76379,82.62796],[-43.40644,83.22516],[-39.89753,83.18018],[-38.62214,83.54905],[-35.08787,83.64513],[-27.10046,83.51966],[-20.84539,82.72669],[-22.69182,82.34165],[-26.51753,82.29765],[-31.9,82.2],[-31.39646,82.02154],[-27.85666,82.13178],[-24.84448,81.78697],[-22.90328,82.09317],[-22.07175,81.73449],[-23.16961,81.15271],[-20.62363,81.52462],[-15.76818,81.91245],[-12.77018,81.71885],[-12.20855,81.29154],[-16.28533,80.58004],[-16.85,80.35],[-20.04624,80.17708],[-17.73035,80.12912],[-18.9,79.4],[-19.70499,78.75128],[-19.67353,77.63859],[-18.47285,76.98565],[-20.03503,76.94434],[-21.67944,76.62795],[-19.83407,76.09808],[-19.59896,75.24838],[-20.66818,75.15585],[-19.37281,74.29561],[-21.59422,74.22382],[-20.43454,73.81713],[-20.76234,73.46436],[-22.17221,73.30955],[-23.56593,73.30663],[-22.31311,72.62928],[-22.29954,72.18409],[-24.27834,72.59788],[-24.79296,72.3302],[-23.44296,72.08016],[-22.13281,71.46898],[-21.75356,70.66369],[-23.53603,70.471],[-24.30702,70.85649],[-25.54341,71.43094],[-25.20135,70.75226],[-26.36276,70.22646],[-23.72742,70.18401],[-22.34902,70.12946],[-25.02927,69.2588],[-27.74737,68.47046],[-30.67371,68.12503],[-31.77665,68.12078],[-32.81105,67.73547],[-34.20196,66.67974],[-36.35284,65.9789],[-37.04378,65.93768],[-38.37505,65.69213],[-39.81222,65.45848],[-40.66899,64.83997],[-40.68281,64.13902],[-41.1887,63.48246],[-42.81938,62.68233],[-42.41666,61.90093],[-42.86619,61.07404],[-43.3784,60.09772],[-44.7875,60.03676],[-46.26364,60.85328],[-48.26294,60.85843],[-49.23308,61.40681],[-49.90039,62.38336],[-51.63325,63.62691],[-52.14014,64.27842],[-52.27659,65.1767],[-53.66166,66.09957],[-53.30161,66.8365],[-53.96911,67.18899],[-52.9804,68.35759],[-51.47536,68.72958],[-51.08041,69.14781],[-50.87122,69.9291],[-52.013585,69.574925],[-52.55792,69.42616],[-53.45629,69.283625],[-54.68336,69.61003],[-54.75001,70.28932],[-54.35884,70.821315],[-53.431315,70.835755],[-51.39014,70.56978],[-53.10937,71.20485],[-54.00422,71.54719],[-55,71.406537],[-55.83468,71.65444],[-54.71819,72.58625],[-55.32634,72.95861],[-56.12003,73.64977],[-57.32363,74.71026],[-58.59679,75.09861],[-58.58516,75.51727],[-61.26861,76.10238],[-63.39165,76.1752],[-66.06427,76.13486],[-68.50438,76.06141],[-69.66485,76.37975],[-71.40257,77.00857],[-68.77671,77.32312],[-66.76397,77.37595],[-71.04293,77.63595],[-73.297,78.04419],[-73.15938,78.43271],[-69.37345,78.91388],[-65.7107,79.39436],[-65.3239,79.75814],[-68.02298,80.11721],[-67.15129,80.51582],[-63.68925,81.21396],[-62.23444,81.3211],[-62.65116,81.77042],[-60.28249,82.03363],[-57.20744,82.19074],[-54.13442,82.19962],[-53.04328,81.88833],[-50.39061,82.43883],[-48.00386,82.06481],[-46.59984,81.985945],[-44.523,81.6607],[-46.9007,82.19979],[-46.76379,82.62796]]]}}, -{"type":"Feature","id":"GTM","properties":{"name":"Guatemala"},"geometry":{"type":"Polygon","coordinates":[[[-90.095555,13.735338],[-90.608624,13.909771],[-91.23241,13.927832],[-91.689747,14.126218],[-92.22775,14.538829],[-92.20323,14.830103],[-92.087216,15.064585],[-92.229249,15.251447],[-91.74796,16.066565],[-90.464473,16.069562],[-90.438867,16.41011],[-90.600847,16.470778],[-90.711822,16.687483],[-91.08167,16.918477],[-91.453921,17.252177],[-91.002269,17.254658],[-91.00152,17.817595],[-90.067934,17.819326],[-89.14308,17.808319],[-89.150806,17.015577],[-89.229122,15.886938],[-88.930613,15.887273],[-88.604586,15.70638],[-88.518364,15.855389],[-88.225023,15.727722],[-88.68068,15.346247],[-89.154811,15.066419],[-89.22522,14.874286],[-89.145535,14.678019],[-89.353326,14.424133],[-89.587343,14.362586],[-89.534219,14.244816],[-89.721934,14.134228],[-90.064678,13.88197],[-90.095555,13.735338]]]}}, -{"type":"Feature","id":"GUF","properties":{"name":"French Guiana"},"geometry":{"type":"Polygon","coordinates":[[[-52.556425,2.504705],[-52.939657,2.124858],[-53.418465,2.053389],[-53.554839,2.334897],[-53.778521,2.376703],[-54.088063,2.105557],[-54.524754,2.311849],[-54.27123,2.738748],[-54.184284,3.194172],[-54.011504,3.62257],[-54.399542,4.212611],[-54.478633,4.896756],[-53.958045,5.756548],[-53.618453,5.646529],[-52.882141,5.409851],[-51.823343,4.565768],[-51.657797,4.156232],[-52.249338,3.241094],[-52.556425,2.504705]]]}}, -{"type":"Feature","id":"GUY","properties":{"name":"Guyana"},"geometry":{"type":"Polygon","coordinates":[[[-59.758285,8.367035],[-59.101684,7.999202],[-58.482962,7.347691],[-58.454876,6.832787],[-58.078103,6.809094],[-57.542219,6.321268],[-57.147436,5.97315],[-57.307246,5.073567],[-57.914289,4.812626],[-57.86021,4.576801],[-58.044694,4.060864],[-57.601569,3.334655],[-57.281433,3.333492],[-57.150098,2.768927],[-56.539386,1.899523],[-56.782704,1.863711],[-57.335823,1.948538],[-57.660971,1.682585],[-58.11345,1.507195],[-58.429477,1.463942],[-58.540013,1.268088],[-59.030862,1.317698],[-59.646044,1.786894],[-59.718546,2.24963],[-59.974525,2.755233],[-59.815413,3.606499],[-59.53804,3.958803],[-59.767406,4.423503],[-60.111002,4.574967],[-59.980959,5.014061],[-60.213683,5.244486],[-60.733574,5.200277],[-61.410303,5.959068],[-61.139415,6.234297],[-61.159336,6.696077],[-60.543999,6.856584],[-60.295668,7.043911],[-60.637973,7.415],[-60.550588,7.779603],[-59.758285,8.367035]]]}}, -{"type":"Feature","id":"HND","properties":{"name":"Honduras"},"geometry":{"type":"Polygon","coordinates":[[[-87.316654,12.984686],[-87.489409,13.297535],[-87.793111,13.38448],[-87.723503,13.78505],[-87.859515,13.893312],[-88.065343,13.964626],[-88.503998,13.845486],[-88.541231,13.980155],[-88.843073,14.140507],[-89.058512,14.340029],[-89.353326,14.424133],[-89.145535,14.678019],[-89.22522,14.874286],[-89.154811,15.066419],[-88.68068,15.346247],[-88.225023,15.727722],[-88.121153,15.688655],[-87.901813,15.864458],[-87.61568,15.878799],[-87.522921,15.797279],[-87.367762,15.84694],[-86.903191,15.756713],[-86.440946,15.782835],[-86.119234,15.893449],[-86.001954,16.005406],[-85.683317,15.953652],[-85.444004,15.885749],[-85.182444,15.909158],[-84.983722,15.995923],[-84.52698,15.857224],[-84.368256,15.835158],[-84.063055,15.648244],[-83.773977,15.424072],[-83.410381,15.270903],[-83.147219,14.995829],[-83.489989,15.016267],[-83.628585,14.880074],[-83.975721,14.749436],[-84.228342,14.748764],[-84.449336,14.621614],[-84.649582,14.666805],[-84.820037,14.819587],[-84.924501,14.790493],[-85.052787,14.551541],[-85.148751,14.560197],[-85.165365,14.35437],[-85.514413,14.079012],[-85.698665,13.960078],[-85.801295,13.836055],[-86.096264,14.038187],[-86.312142,13.771356],[-86.520708,13.778487],[-86.755087,13.754845],[-86.733822,13.263093],[-86.880557,13.254204],[-87.005769,13.025794],[-87.316654,12.984686]]]}}, -{"type":"Feature","id":"HRV","properties":{"name":"Croatia"},"geometry":{"type":"Polygon","coordinates":[[[18.829838,45.908878],[19.072769,45.521511],[19.390476,45.236516],[19.005486,44.860234],[18.553214,45.08159],[17.861783,45.06774],[17.002146,45.233777],[16.534939,45.211608],[16.318157,45.004127],[15.959367,45.233777],[15.750026,44.818712],[16.23966,44.351143],[16.456443,44.04124],[16.916156,43.667722],[17.297373,43.446341],[17.674922,43.028563],[18.56,42.65],[18.450016,42.479991],[17.50997,42.849995],[16.930006,43.209998],[16.015385,43.507215],[15.174454,44.243191],[15.37625,44.317915],[14.920309,44.738484],[14.901602,45.07606],[14.258748,45.233777],[13.952255,44.802124],[13.656976,45.136935],[13.679403,45.484149],[13.71506,45.500324],[14.411968,45.466166],[14.595109,45.634941],[14.935244,45.471695],[15.327675,45.452316],[15.323954,45.731783],[15.67153,45.834154],[15.768733,46.238108],[16.564808,46.503751],[16.882515,46.380632],[17.630066,45.951769],[18.456062,45.759481],[18.829838,45.908878]]]}}, -{"type":"Feature","id":"HTI","properties":{"name":"Haiti"},"geometry":{"type":"Polygon","coordinates":[[[-73.189791,19.915684],[-72.579673,19.871501],[-71.712361,19.714456],[-71.624873,19.169838],[-71.701303,18.785417],[-71.945112,18.6169],[-71.687738,18.31666],[-71.708305,18.044997],[-72.372476,18.214961],[-72.844411,18.145611],[-73.454555,18.217906],[-73.922433,18.030993],[-74.458034,18.34255],[-74.369925,18.664908],[-73.449542,18.526053],[-72.694937,18.445799],[-72.334882,18.668422],[-72.79165,19.101625],[-72.784105,19.483591],[-73.415022,19.639551],[-73.189791,19.915684]]]}}, -{"type":"Feature","id":"HUN","properties":{"name":"Hungary"},"geometry":{"type":"Polygon","coordinates":[[[16.202298,46.852386],[16.534268,47.496171],[16.340584,47.712902],[16.903754,47.714866],[16.979667,48.123497],[17.488473,47.867466],[17.857133,47.758429],[18.696513,47.880954],[18.777025,48.081768],[19.174365,48.111379],[19.661364,48.266615],[19.769471,48.202691],[20.239054,48.327567],[20.473562,48.56285],[20.801294,48.623854],[21.872236,48.319971],[22.085608,48.422264],[22.64082,48.15024],[22.710531,47.882194],[22.099768,47.672439],[21.626515,46.994238],[21.021952,46.316088],[20.220192,46.127469],[19.596045,46.17173],[18.829838,45.908878],[18.456062,45.759481],[17.630066,45.951769],[16.882515,46.380632],[16.564808,46.503751],[16.370505,46.841327],[16.202298,46.852386]]]}}, -{"type":"Feature","id":"IDN","properties":{"name":"Indonesia"},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.715609,-10.239581],[120.295014,-10.25865],[118.967808,-9.557969],[119.90031,-9.36134],[120.425756,-9.665921],[120.775502,-9.969675],[120.715609,-10.239581]]],[[[124.43595,-10.140001],[123.579982,-10.359987],[123.459989,-10.239995],[123.550009,-9.900016],[123.980009,-9.290027],[124.968682,-8.89279],[125.07002,-9.089987],[125.08852,-9.393173],[124.43595,-10.140001]]],[[[117.900018,-8.095681],[118.260616,-8.362383],[118.87846,-8.280683],[119.126507,-8.705825],[117.970402,-8.906639],[117.277731,-9.040895],[116.740141,-9.032937],[117.083737,-8.457158],[117.632024,-8.449303],[117.900018,-8.095681]]],[[[122.903537,-8.094234],[122.756983,-8.649808],[121.254491,-8.933666],[119.924391,-8.810418],[119.920929,-8.444859],[120.715092,-8.236965],[121.341669,-8.53674],[122.007365,-8.46062],[122.903537,-8.094234]]],[[[108.623479,-6.777674],[110.539227,-6.877358],[110.759576,-6.465186],[112.614811,-6.946036],[112.978768,-7.594213],[114.478935,-7.776528],[115.705527,-8.370807],[114.564511,-8.751817],[113.464734,-8.348947],[112.559672,-8.376181],[111.522061,-8.302129],[110.58615,-8.122605],[109.427667,-7.740664],[108.693655,-7.6416],[108.277763,-7.766657],[106.454102,-7.3549],[106.280624,-6.9249],[105.365486,-6.851416],[106.051646,-5.895919],[107.265009,-5.954985],[108.072091,-6.345762],[108.486846,-6.421985],[108.623479,-6.777674]]],[[[134.724624,-6.214401],[134.210134,-6.895238],[134.112776,-6.142467],[134.290336,-5.783058],[134.499625,-5.445042],[134.727002,-5.737582],[134.724624,-6.214401]]],[[[127.249215,-3.459065],[126.874923,-3.790983],[126.183802,-3.607376],[125.989034,-3.177273],[127.000651,-3.129318],[127.249215,-3.459065]]],[[[130.471344,-3.093764],[130.834836,-3.858472],[129.990547,-3.446301],[129.155249,-3.362637],[128.590684,-3.428679],[127.898891,-3.393436],[128.135879,-2.84365],[129.370998,-2.802154],[130.471344,-3.093764]]],[[[134.143368,-1.151867],[134.422627,-2.769185],[135.457603,-3.367753],[136.293314,-2.307042],[137.440738,-1.703513],[138.329727,-1.702686],[139.184921,-2.051296],[139.926684,-2.409052],[141.00021,-2.600151],[141.017057,-5.859022],[141.033852,-9.117893],[140.143415,-8.297168],[139.127767,-8.096043],[138.881477,-8.380935],[137.614474,-8.411683],[138.039099,-7.597882],[138.668621,-7.320225],[138.407914,-6.232849],[137.92784,-5.393366],[135.98925,-4.546544],[135.164598,-4.462931],[133.66288,-3.538853],[133.367705,-4.024819],[132.983956,-4.112979],[132.756941,-3.746283],[132.753789,-3.311787],[131.989804,-2.820551],[133.066845,-2.460418],[133.780031,-2.479848],[133.696212,-2.214542],[132.232373,-2.212526],[131.836222,-1.617162],[130.94284,-1.432522],[130.519558,-0.93772],[131.867538,-0.695461],[132.380116,-0.369538],[133.985548,-0.78021],[134.143368,-1.151867]]],[[[125.240501,1.419836],[124.437035,0.427881],[123.685505,0.235593],[122.723083,0.431137],[121.056725,0.381217],[120.183083,0.237247],[120.04087,-0.519658],[120.935905,-1.408906],[121.475821,-0.955962],[123.340565,-0.615673],[123.258399,-1.076213],[122.822715,-0.930951],[122.38853,-1.516858],[121.508274,-1.904483],[122.454572,-3.186058],[122.271896,-3.5295],[123.170963,-4.683693],[123.162333,-5.340604],[122.628515,-5.634591],[122.236394,-5.282933],[122.719569,-4.464172],[121.738234,-4.851331],[121.489463,-4.574553],[121.619171,-4.188478],[120.898182,-3.602105],[120.972389,-2.627643],[120.305453,-2.931604],[120.390047,-4.097579],[120.430717,-5.528241],[119.796543,-5.6734],[119.366906,-5.379878],[119.653606,-4.459417],[119.498835,-3.494412],[119.078344,-3.487022],[118.767769,-2.801999],[119.180974,-2.147104],[119.323394,-1.353147],[119.825999,0.154254],[120.035702,0.566477],[120.885779,1.309223],[121.666817,1.013944],[122.927567,0.875192],[124.077522,0.917102],[125.065989,1.643259],[125.240501,1.419836]]],[[[128.688249,1.132386],[128.635952,0.258486],[128.12017,0.356413],[127.968034,-0.252077],[128.379999,-0.780004],[128.100016,-0.899996],[127.696475,-0.266598],[127.39949,1.011722],[127.600512,1.810691],[127.932378,2.174596],[128.004156,1.628531],[128.594559,1.540811],[128.688249,1.132386]]],[[[117.875627,1.827641],[118.996747,0.902219],[117.811858,0.784242],[117.478339,0.102475],[117.521644,-0.803723],[116.560048,-1.487661],[116.533797,-2.483517],[116.148084,-4.012726],[116.000858,-3.657037],[114.864803,-4.106984],[114.468652,-3.495704],[113.755672,-3.43917],[113.256994,-3.118776],[112.068126,-3.478392],[111.703291,-2.994442],[111.04824,-3.049426],[110.223846,-2.934032],[110.070936,-1.592874],[109.571948,-1.314907],[109.091874,-0.459507],[108.952658,0.415375],[109.069136,1.341934],[109.66326,2.006467],[109.830227,1.338136],[110.514061,0.773131],[111.159138,0.976478],[111.797548,0.904441],[112.380252,1.410121],[112.859809,1.49779],[113.80585,1.217549],[114.621355,1.430688],[115.134037,2.821482],[115.519078,3.169238],[115.865517,4.306559],[117.015214,4.306094],[117.882035,4.137551],[117.313232,3.234428],[118.04833,2.28769],[117.875627,1.827641]]],[[[105.817655,-5.852356],[104.710384,-5.873285],[103.868213,-5.037315],[102.584261,-4.220259],[102.156173,-3.614146],[101.399113,-2.799777],[100.902503,-2.050262],[100.141981,-0.650348],[99.26374,0.183142],[98.970011,1.042882],[98.601351,1.823507],[97.699598,2.453184],[97.176942,3.308791],[96.424017,3.86886],[95.380876,4.970782],[95.293026,5.479821],[95.936863,5.439513],[97.484882,5.246321],[98.369169,4.26837],[99.142559,3.59035],[99.693998,3.174329],[100.641434,2.099381],[101.658012,2.083697],[102.498271,1.3987],[103.07684,0.561361],[103.838396,0.104542],[103.437645,-0.711946],[104.010789,-1.059212],[104.369991,-1.084843],[104.53949,-1.782372],[104.887893,-2.340425],[105.622111,-2.428844],[106.108593,-3.061777],[105.857446,-4.305525],[105.817655,-5.852356]]]]}}, -{"type":"Feature","id":"IND","properties":{"name":"India"},"geometry":{"type":"Polygon","coordinates":[[[77.837451,35.49401],[78.912269,34.321936],[78.811086,33.506198],[79.208892,32.994395],[79.176129,32.48378],[78.458446,32.618164],[78.738894,31.515906],[79.721367,30.882715],[81.111256,30.183481],[80.476721,29.729865],[80.088425,28.79447],[81.057203,28.416095],[81.999987,27.925479],[83.304249,27.364506],[84.675018,27.234901],[85.251779,26.726198],[86.024393,26.630985],[87.227472,26.397898],[88.060238,26.414615],[88.174804,26.810405],[88.043133,27.445819],[88.120441,27.876542],[88.730326,28.086865],[88.814248,27.299316],[88.835643,27.098966],[89.744528,26.719403],[90.373275,26.875724],[91.217513,26.808648],[92.033484,26.83831],[92.103712,27.452614],[91.696657,27.771742],[92.503119,27.896876],[93.413348,28.640629],[94.56599,29.277438],[95.404802,29.031717],[96.117679,29.452802],[96.586591,28.83098],[96.248833,28.411031],[97.327114,28.261583],[97.402561,27.882536],[97.051989,27.699059],[97.133999,27.083774],[96.419366,27.264589],[95.124768,26.573572],[95.155153,26.001307],[94.603249,25.162495],[94.552658,24.675238],[94.106742,23.850741],[93.325188,24.078556],[93.286327,23.043658],[93.060294,22.703111],[93.166128,22.27846],[92.672721,22.041239],[92.146035,23.627499],[91.869928,23.624346],[91.706475,22.985264],[91.158963,23.503527],[91.46773,24.072639],[91.915093,24.130414],[92.376202,24.976693],[91.799596,25.147432],[90.872211,25.132601],[89.920693,25.26975],[89.832481,25.965082],[89.355094,26.014407],[88.563049,26.446526],[88.209789,25.768066],[88.931554,25.238692],[88.306373,24.866079],[88.084422,24.501657],[88.69994,24.233715],[88.52977,23.631142],[88.876312,22.879146],[89.031961,22.055708],[88.888766,21.690588],[88.208497,21.703172],[86.975704,21.495562],[87.033169,20.743308],[86.499351,20.151638],[85.060266,19.478579],[83.941006,18.30201],[83.189217,17.671221],[82.192792,17.016636],[82.191242,16.556664],[81.692719,16.310219],[80.791999,15.951972],[80.324896,15.899185],[80.025069,15.136415],[80.233274,13.835771],[80.286294,13.006261],[79.862547,12.056215],[79.857999,10.357275],[79.340512,10.308854],[78.885345,9.546136],[79.18972,9.216544],[78.277941,8.933047],[77.941165,8.252959],[77.539898,7.965535],[76.592979,8.899276],[76.130061,10.29963],[75.746467,11.308251],[75.396101,11.781245],[74.864816,12.741936],[74.616717,13.992583],[74.443859,14.617222],[73.534199,15.990652],[73.119909,17.92857],[72.820909,19.208234],[72.824475,20.419503],[72.630533,21.356009],[71.175273,20.757441],[70.470459,20.877331],[69.16413,22.089298],[69.644928,22.450775],[69.349597,22.84318],[68.176645,23.691965],[68.842599,24.359134],[71.04324,24.356524],[70.844699,25.215102],[70.282873,25.722229],[70.168927,26.491872],[69.514393,26.940966],[70.616496,27.989196],[71.777666,27.91318],[72.823752,28.961592],[73.450638,29.976413],[74.42138,30.979815],[74.405929,31.692639],[75.258642,32.271105],[74.451559,32.7649],[74.104294,33.441473],[73.749948,34.317699],[74.240203,34.748887],[75.757061,34.504923],[76.871722,34.653544],[77.837451,35.49401]]]}}, -{"type":"Feature","id":"IRL","properties":{"name":"Ireland"},"geometry":{"type":"Polygon","coordinates":[[[-6.197885,53.867565],[-6.032985,53.153164],[-6.788857,52.260118],[-8.561617,51.669301],[-9.977086,51.820455],[-9.166283,52.864629],[-9.688525,53.881363],[-8.327987,54.664519],[-7.572168,55.131622],[-7.366031,54.595841],[-7.572168,54.059956],[-6.95373,54.073702],[-6.197885,53.867565]]]}}, -{"type":"Feature","id":"IRN","properties":{"name":"Iran"},"geometry":{"type":"Polygon","coordinates":[[[53.921598,37.198918],[54.800304,37.392421],[55.511578,37.964117],[56.180375,37.935127],[56.619366,38.121394],[57.330434,38.029229],[58.436154,37.522309],[59.234762,37.412988],[60.377638,36.527383],[61.123071,36.491597],[61.210817,35.650072],[60.803193,34.404102],[60.52843,33.676446],[60.9637,33.528832],[60.536078,32.981269],[60.863655,32.18292],[60.941945,31.548075],[61.699314,31.379506],[61.781222,30.73585],[60.874248,29.829239],[61.369309,29.303276],[61.771868,28.699334],[62.72783,28.259645],[62.755426,27.378923],[63.233898,27.217047],[63.316632,26.756532],[61.874187,26.239975],[61.497363,25.078237],[59.616134,25.380157],[58.525761,25.609962],[57.397251,25.739902],[56.970766,26.966106],[56.492139,27.143305],[55.72371,26.964633],[54.71509,26.480658],[53.493097,26.812369],[52.483598,27.580849],[51.520763,27.86569],[50.852948,28.814521],[50.115009,30.147773],[49.57685,29.985715],[48.941333,30.31709],[48.567971,29.926778],[48.014568,30.452457],[48.004698,30.985137],[47.685286,30.984853],[47.849204,31.709176],[47.334661,32.469155],[46.109362,33.017287],[45.416691,33.967798],[45.64846,34.748138],[46.151788,35.093259],[46.07634,35.677383],[45.420618,35.977546],[44.77267,37.17045],[44.225756,37.971584],[44.421403,38.281281],[44.109225,39.428136],[44.79399,39.713003],[44.952688,39.335765],[45.457722,38.874139],[46.143623,38.741201],[46.50572,38.770605],[47.685079,39.508364],[48.060095,39.582235],[48.355529,39.288765],[48.010744,38.794015],[48.634375,38.270378],[48.883249,38.320245],[49.199612,37.582874],[50.147771,37.374567],[50.842354,36.872814],[52.264025,36.700422],[53.82579,36.965031],[53.921598,37.198918]]]}}, -{"type":"Feature","id":"IRQ","properties":{"name":"Iraq"},"geometry":{"type":"Polygon","coordinates":[[[45.420618,35.977546],[46.07634,35.677383],[46.151788,35.093259],[45.64846,34.748138],[45.416691,33.967798],[46.109362,33.017287],[47.334661,32.469155],[47.849204,31.709176],[47.685286,30.984853],[48.004698,30.985137],[48.014568,30.452457],[48.567971,29.926778],[47.974519,29.975819],[47.302622,30.05907],[46.568713,29.099025],[44.709499,29.178891],[41.889981,31.190009],[40.399994,31.889992],[39.195468,32.161009],[38.792341,33.378686],[41.006159,34.419372],[41.383965,35.628317],[41.289707,36.358815],[41.837064,36.605854],[42.349591,37.229873],[42.779126,37.385264],[43.942259,37.256228],[44.293452,37.001514],[44.772699,37.170445],[45.420618,35.977546]]]}}, -{"type":"Feature","id":"ISL","properties":{"name":"Iceland"},"geometry":{"type":"Polygon","coordinates":[[[-14.508695,66.455892],[-14.739637,65.808748],[-13.609732,65.126671],[-14.909834,64.364082],[-17.794438,63.678749],[-18.656246,63.496383],[-19.972755,63.643635],[-22.762972,63.960179],[-21.778484,64.402116],[-23.955044,64.89113],[-22.184403,65.084968],[-22.227423,65.378594],[-24.326184,65.611189],[-23.650515,66.262519],[-22.134922,66.410469],[-20.576284,65.732112],[-19.056842,66.276601],[-17.798624,65.993853],[-16.167819,66.526792],[-14.508695,66.455892]]]}}, -{"type":"Feature","id":"ISR","properties":{"name":"Israel"},"geometry":{"type":"Polygon","coordinates":[[[35.719918,32.709192],[35.545665,32.393992],[35.18393,32.532511],[34.974641,31.866582],[35.225892,31.754341],[34.970507,31.616778],[34.927408,31.353435],[35.397561,31.489086],[35.420918,31.100066],[34.922603,29.501326],[34.265433,31.219361],[34.556372,31.548824],[34.488107,31.605539],[34.752587,32.072926],[34.955417,32.827376],[35.098457,33.080539],[35.126053,33.0909],[35.460709,33.08904],[35.552797,33.264275],[35.821101,33.277426],[35.836397,32.868123],[35.700798,32.716014],[35.719918,32.709192]]]}}, -{"type":"Feature","id":"ITA","properties":{"name":"Italy"},"geometry":{"type":"MultiPolygon","coordinates":[[[[15.520376,38.231155],[15.160243,37.444046],[15.309898,37.134219],[15.099988,36.619987],[14.335229,36.996631],[13.826733,37.104531],[12.431004,37.61295],[12.570944,38.126381],[13.741156,38.034966],[14.761249,38.143874],[15.520376,38.231155]]],[[[9.210012,41.209991],[9.809975,40.500009],[9.669519,39.177376],[9.214818,39.240473],[8.806936,38.906618],[8.428302,39.171847],[8.388253,40.378311],[8.159998,40.950007],[8.709991,40.899984],[9.210012,41.209991]]],[[[12.376485,46.767559],[13.806475,46.509306],[13.69811,46.016778],[13.93763,45.591016],[13.141606,45.736692],[12.328581,45.381778],[12.383875,44.885374],[12.261453,44.600482],[12.589237,44.091366],[13.526906,43.587727],[14.029821,42.761008],[15.14257,41.95514],[15.926191,41.961315],[16.169897,41.740295],[15.889346,41.541082],[16.785002,41.179606],[17.519169,40.877143],[18.376687,40.355625],[18.480247,40.168866],[18.293385,39.810774],[17.73838,40.277671],[16.869596,40.442235],[16.448743,39.795401],[17.17149,39.4247],[17.052841,38.902871],[16.635088,38.843572],[16.100961,37.985899],[15.684087,37.908849],[15.687963,38.214593],[15.891981,38.750942],[16.109332,38.964547],[15.718814,39.544072],[15.413613,40.048357],[14.998496,40.172949],[14.703268,40.60455],[14.060672,40.786348],[13.627985,41.188287],[12.888082,41.25309],[12.106683,41.704535],[11.191906,42.355425],[10.511948,42.931463],[10.200029,43.920007],[9.702488,44.036279],[8.888946,44.366336],[8.428561,44.231228],[7.850767,43.767148],[7.435185,43.693845],[7.549596,44.127901],[7.007562,44.254767],[6.749955,45.028518],[7.096652,45.333099],[6.802355,45.70858],[6.843593,45.991147],[7.273851,45.776948],[7.755992,45.82449],[8.31663,46.163642],[8.489952,46.005151],[8.966306,46.036932],[9.182882,46.440215],[9.922837,46.314899],[10.363378,46.483571],[10.442701,46.893546],[11.048556,46.751359],[11.164828,46.941579],[12.153088,47.115393],[12.376485,46.767559]]]]}}, -{"type":"Feature","id":"JAM","properties":{"name":"Jamaica"},"geometry":{"type":"Polygon","coordinates":[[[-77.569601,18.490525],[-76.896619,18.400867],[-76.365359,18.160701],[-76.199659,17.886867],[-76.902561,17.868238],[-77.206341,17.701116],[-77.766023,17.861597],[-78.337719,18.225968],[-78.217727,18.454533],[-77.797365,18.524218],[-77.569601,18.490525]]]}}, -{"type":"Feature","id":"JOR","properties":{"name":"Jordan"},"geometry":{"type":"Polygon","coordinates":[[[35.545665,32.393992],[35.719918,32.709192],[36.834062,32.312938],[38.792341,33.378686],[39.195468,32.161009],[39.004886,32.010217],[37.002166,31.508413],[37.998849,30.5085],[37.66812,30.338665],[37.503582,30.003776],[36.740528,29.865283],[36.501214,29.505254],[36.068941,29.197495],[34.956037,29.356555],[34.922603,29.501326],[35.420918,31.100066],[35.397561,31.489086],[35.545252,31.782505],[35.545665,32.393992]]]}}, -{"type":"Feature","id":"JPN","properties":{"name":"Japan"},"geometry":{"type":"MultiPolygon","coordinates":[[[[134.638428,34.149234],[134.766379,33.806335],[134.203416,33.201178],[133.79295,33.521985],[133.280268,33.28957],[133.014858,32.704567],[132.363115,32.989382],[132.371176,33.463642],[132.924373,34.060299],[133.492968,33.944621],[133.904106,34.364931],[134.638428,34.149234]]],[[[140.976388,37.142074],[140.59977,36.343983],[140.774074,35.842877],[140.253279,35.138114],[138.975528,34.6676],[137.217599,34.606286],[135.792983,33.464805],[135.120983,33.849071],[135.079435,34.596545],[133.340316,34.375938],[132.156771,33.904933],[130.986145,33.885761],[132.000036,33.149992],[131.33279,31.450355],[130.686318,31.029579],[130.20242,31.418238],[130.447676,32.319475],[129.814692,32.61031],[129.408463,33.296056],[130.353935,33.604151],[130.878451,34.232743],[131.884229,34.749714],[132.617673,35.433393],[134.608301,35.731618],[135.677538,35.527134],[136.723831,37.304984],[137.390612,36.827391],[138.857602,37.827485],[139.426405,38.215962],[140.05479,39.438807],[139.883379,40.563312],[140.305783,41.195005],[141.368973,41.37856],[141.914263,39.991616],[141.884601,39.180865],[140.959489,38.174001],[140.976388,37.142074]]],[[[143.910162,44.1741],[144.613427,43.960883],[145.320825,44.384733],[145.543137,43.262088],[144.059662,42.988358],[143.18385,41.995215],[141.611491,42.678791],[141.067286,41.584594],[139.955106,41.569556],[139.817544,42.563759],[140.312087,43.333273],[141.380549,43.388825],[141.671952,44.772125],[141.967645,45.551483],[143.14287,44.510358],[143.910162,44.1741]]]]}}, -{"type":"Feature","id":"KAZ","properties":{"name":"Kazakhstan"},"geometry":{"type":"Polygon","coordinates":[[[70.962315,42.266154],[70.388965,42.081308],[69.070027,41.384244],[68.632483,40.668681],[68.259896,40.662325],[67.985856,41.135991],[66.714047,41.168444],[66.510649,41.987644],[66.023392,41.994646],[66.098012,42.99766],[64.900824,43.728081],[63.185787,43.650075],[62.0133,43.504477],[61.05832,44.405817],[60.239972,44.784037],[58.689989,45.500014],[58.503127,45.586804],[55.928917,44.995858],[55.968191,41.308642],[55.455251,41.259859],[54.755345,42.043971],[54.079418,42.324109],[52.944293,42.116034],[52.50246,41.783316],[52.446339,42.027151],[52.692112,42.443895],[52.501426,42.792298],[51.342427,43.132975],[50.891292,44.031034],[50.339129,44.284016],[50.305643,44.609836],[51.278503,44.514854],[51.316899,45.245998],[52.16739,45.408391],[53.040876,45.259047],[53.220866,46.234646],[53.042737,46.853006],[52.042023,46.804637],[51.191945,47.048705],[50.034083,46.60899],[49.10116,46.39933],[48.593241,46.561034],[48.694734,47.075628],[48.057253,47.743753],[47.315231,47.715847],[46.466446,48.394152],[47.043672,49.152039],[46.751596,49.356006],[47.54948,50.454698],[48.577841,49.87476],[48.702382,50.605128],[50.766648,51.692762],[52.328724,51.718652],[54.532878,51.02624],[55.716941,50.621717],[56.777961,51.043551],[58.363291,51.063653],[59.642282,50.545442],[59.932807,50.842194],[61.337424,50.79907],[61.588003,51.272659],[59.967534,51.96042],[60.927269,52.447548],[60.739993,52.719986],[61.699986,52.979996],[60.978066,53.664993],[61.436591,54.006265],[65.178534,54.354228],[65.666876,54.601267],[68.1691,54.970392],[69.068167,55.38525],[70.865267,55.169734],[71.180131,54.133285],[72.22415,54.376655],[73.508516,54.035617],[73.425679,53.48981],[74.384845,53.546861],[76.8911,54.490524],[76.525179,54.177003],[77.800916,53.404415],[80.03556,50.864751],[80.568447,51.388336],[81.945986,50.812196],[83.383004,51.069183],[83.935115,50.889246],[84.416377,50.3114],[85.11556,50.117303],[85.54127,49.692859],[86.829357,49.826675],[87.35997,49.214981],[86.598776,48.549182],[85.768233,48.455751],[85.720484,47.452969],[85.16429,47.000956],[83.180484,47.330031],[82.458926,45.53965],[81.947071,45.317027],[79.966106,44.917517],[80.866206,43.180362],[80.18015,42.920068],[80.25999,42.349999],[79.643645,42.496683],[79.142177,42.856092],[77.658392,42.960686],[76.000354,42.988022],[75.636965,42.8779],[74.212866,43.298339],[73.645304,43.091272],[73.489758,42.500894],[71.844638,42.845395],[71.186281,42.704293],[70.962315,42.266154]]]}}, -{"type":"Feature","id":"KEN","properties":{"name":"Kenya"},"geometry":{"type":"Polygon","coordinates":[[[40.993,-0.85829],[41.58513,-1.68325],[40.88477,-2.08255],[40.63785,-2.49979],[40.26304,-2.57309],[40.12119,-3.27768],[39.80006,-3.68116],[39.60489,-4.34653],[39.20222,-4.67677],[37.7669,-3.67712],[37.69869,-3.09699],[34.07262,-1.05982],[33.903711,-0.95],[33.893569,0.109814],[34.18,0.515],[34.6721,1.17694],[35.03599,1.90584],[34.59607,3.05374],[34.47913,3.5556],[34.005,4.249885],[34.620196,4.847123],[35.298007,5.506],[35.817448,5.338232],[35.817448,4.776966],[36.159079,4.447864],[36.855093,4.447864],[38.120915,3.598605],[38.43697,3.58851],[38.67114,3.61607],[38.89251,3.50074],[39.559384,3.42206],[39.85494,3.83879],[40.76848,4.25702],[41.1718,3.91909],[41.855083,3.918912],[40.98105,2.78452],[40.993,-0.85829]]]}}, -{"type":"Feature","id":"KGZ","properties":{"name":"Kyrgyzstan"},"geometry":{"type":"Polygon","coordinates":[[[70.962315,42.266154],[71.186281,42.704293],[71.844638,42.845395],[73.489758,42.500894],[73.645304,43.091272],[74.212866,43.298339],[75.636965,42.8779],[76.000354,42.988022],[77.658392,42.960686],[79.142177,42.856092],[79.643645,42.496683],[80.25999,42.349999],[80.11943,42.123941],[78.543661,41.582243],[78.187197,41.185316],[76.904484,41.066486],[76.526368,40.427946],[75.467828,40.562072],[74.776862,40.366425],[73.822244,39.893973],[73.960013,39.660008],[73.675379,39.431237],[71.784694,39.279463],[70.549162,39.604198],[69.464887,39.526683],[69.55961,40.103211],[70.648019,39.935754],[71.014198,40.244366],[71.774875,40.145844],[73.055417,40.866033],[71.870115,41.3929],[71.157859,41.143587],[70.420022,41.519998],[71.259248,42.167711],[70.962315,42.266154]]]}}, -{"type":"Feature","id":"KHM","properties":{"name":"Cambodia"},"geometry":{"type":"Polygon","coordinates":[[[103.49728,10.632555],[103.09069,11.153661],[102.584932,12.186595],[102.348099,13.394247],[102.988422,14.225721],[104.281418,14.416743],[105.218777,14.273212],[106.043946,13.881091],[106.496373,14.570584],[107.382727,14.202441],[107.614548,13.535531],[107.491403,12.337206],[105.810524,11.567615],[106.24967,10.961812],[105.199915,10.88931],[104.334335,10.486544],[103.49728,10.632555]]]}}, -{"type":"Feature","id":"KOR","properties":{"name":"South Korea"},"geometry":{"type":"Polygon","coordinates":[[[128.349716,38.612243],[129.21292,37.432392],[129.46045,36.784189],[129.468304,35.632141],[129.091377,35.082484],[128.18585,34.890377],[127.386519,34.475674],[126.485748,34.390046],[126.37392,34.93456],[126.559231,35.684541],[126.117398,36.725485],[126.860143,36.893924],[126.174759,37.749686],[126.237339,37.840378],[126.68372,37.804773],[127.073309,38.256115],[127.780035,38.304536],[128.205746,38.370397],[128.349716,38.612243]]]}}, -{"type":"Feature","id":"CS-KM","properties":{"name":"Kosovo"},"geometry":{"type":"Polygon","coordinates":[[[20.76216,42.05186],[20.71731,41.84711],[20.59023,41.85541],[20.52295,42.21787],[20.28374,42.32025],[20.0707,42.58863],[20.25758,42.81275],[20.49679,42.88469],[20.63508,43.21671],[20.81448,43.27205],[20.95651,43.13094],[21.143395,43.068685],[21.27421,42.90959],[21.43866,42.86255],[21.63302,42.67717],[21.77505,42.6827],[21.66292,42.43922],[21.54332,42.32025],[21.576636,42.245224],[21.3527,42.2068],[20.76216,42.05186]]]}}, -{"type":"Feature","id":"KWT","properties":{"name":"Kuwait"},"geometry":{"type":"Polygon","coordinates":[[[47.974519,29.975819],[48.183189,29.534477],[48.093943,29.306299],[48.416094,28.552004],[47.708851,28.526063],[47.459822,29.002519],[46.568713,29.099025],[47.302622,30.05907],[47.974519,29.975819]]]}}, -{"type":"Feature","id":"LAO","properties":{"name":"Laos"},"geometry":{"type":"Polygon","coordinates":[[[105.218777,14.273212],[105.544338,14.723934],[105.589039,15.570316],[104.779321,16.441865],[104.716947,17.428859],[103.956477,18.240954],[103.200192,18.309632],[102.998706,17.961695],[102.413005,17.932782],[102.113592,18.109102],[101.059548,17.512497],[101.035931,18.408928],[101.282015,19.462585],[100.606294,19.508344],[100.548881,20.109238],[100.115988,20.41785],[100.329101,20.786122],[101.180005,21.436573],[101.270026,21.201652],[101.80312,21.174367],[101.652018,22.318199],[102.170436,22.464753],[102.754896,21.675137],[103.203861,20.766562],[104.435,20.758733],[104.822574,19.886642],[104.183388,19.624668],[103.896532,19.265181],[105.094598,18.666975],[105.925762,17.485315],[106.556008,16.604284],[107.312706,15.908538],[107.564525,15.202173],[107.382727,14.202441],[106.496373,14.570584],[106.043946,13.881091],[105.218777,14.273212]]]}}, -{"type":"Feature","id":"LBN","properties":{"name":"Lebanon"},"geometry":{"type":"Polygon","coordinates":[[[35.821101,33.277426],[35.552797,33.264275],[35.460709,33.08904],[35.126053,33.0909],[35.482207,33.90545],[35.979592,34.610058],[35.998403,34.644914],[36.448194,34.593935],[36.61175,34.201789],[36.06646,33.824912],[35.821101,33.277426]]]}}, -{"type":"Feature","id":"LBR","properties":{"name":"Liberia"},"geometry":{"type":"Polygon","coordinates":[[[-7.712159,4.364566],[-7.974107,4.355755],[-9.004794,4.832419],[-9.91342,5.593561],[-10.765384,6.140711],[-11.438779,6.785917],[-11.199802,7.105846],[-11.146704,7.396706],[-10.695595,7.939464],[-10.230094,8.406206],[-10.016567,8.428504],[-9.755342,8.541055],[-9.33728,7.928534],[-9.403348,7.526905],[-9.208786,7.313921],[-8.926065,7.309037],[-8.722124,7.711674],[-8.439298,7.686043],[-8.485446,7.395208],[-8.385452,6.911801],[-8.60288,6.467564],[-8.311348,6.193033],[-7.993693,6.12619],[-7.570153,5.707352],[-7.539715,5.313345],[-7.635368,5.188159],[-7.712159,4.364566]]]}}, -{"type":"Feature","id":"LBY","properties":{"name":"Libya"},"geometry":{"type":"Polygon","coordinates":[[[14.8513,22.86295],[14.143871,22.491289],[13.581425,23.040506],[11.999506,23.471668],[11.560669,24.097909],[10.771364,24.562532],[10.303847,24.379313],[9.948261,24.936954],[9.910693,25.365455],[9.319411,26.094325],[9.716286,26.512206],[9.629056,27.140953],[9.756128,27.688259],[9.683885,28.144174],[9.859998,28.95999],[9.805634,29.424638],[9.48214,30.307556],[9.970017,30.539325],[10.056575,30.961831],[9.950225,31.37607],[10.636901,31.761421],[10.94479,32.081815],[11.432253,32.368903],[11.488787,33.136996],[12.66331,32.79278],[13.08326,32.87882],[13.91868,32.71196],[15.24563,32.26508],[15.71394,31.37626],[16.61162,31.18218],[18.02109,30.76357],[19.08641,30.26639],[19.57404,30.52582],[20.05335,30.98576],[19.82033,31.75179],[20.13397,32.2382],[20.85452,32.7068],[21.54298,32.8432],[22.89576,32.63858],[23.2368,32.19149],[23.60913,32.18726],[23.9275,32.01667],[24.92114,31.89936],[25.16482,31.56915],[24.80287,31.08929],[24.95762,30.6616],[24.70007,30.04419],[25,29.238655],[25,25.6825],[25,22],[25,20.00304],[23.85,20],[23.83766,19.58047],[19.84926,21.49509],[15.86085,23.40972],[14.8513,22.86295]]]}}, -{"type":"Feature","id":"LKA","properties":{"name":"Sri Lanka"},"geometry":{"type":"Polygon","coordinates":[[[81.787959,7.523055],[81.637322,6.481775],[81.21802,6.197141],[80.348357,5.96837],[79.872469,6.763463],[79.695167,8.200843],[80.147801,9.824078],[80.838818,9.268427],[81.304319,8.564206],[81.787959,7.523055]]]}}, -{"type":"Feature","id":"LSO","properties":{"name":"Lesotho"},"geometry":{"type":"Polygon","coordinates":[[[28.978263,-28.955597],[29.325166,-29.257387],[29.018415,-29.743766],[28.8484,-30.070051],[28.291069,-30.226217],[28.107205,-30.545732],[27.749397,-30.645106],[26.999262,-29.875954],[27.532511,-29.242711],[28.074338,-28.851469],[28.5417,-28.647502],[28.978263,-28.955597]]]}}, -{"type":"Feature","id":"LTU","properties":{"name":"Lithuania"},"geometry":{"type":"Polygon","coordinates":[[[22.731099,54.327537],[22.651052,54.582741],[22.757764,54.856574],[22.315724,55.015299],[21.268449,55.190482],[21.0558,56.031076],[22.201157,56.337802],[23.878264,56.273671],[24.860684,56.372528],[25.000934,56.164531],[25.533047,56.100297],[26.494331,55.615107],[26.588279,55.167176],[25.768433,54.846963],[25.536354,54.282423],[24.450684,53.905702],[23.484128,53.912498],[23.243987,54.220567],[22.731099,54.327537]]]}}, -{"type":"Feature","id":"LUX","properties":{"name":"Luxembourg"},"geometry":{"type":"Polygon","coordinates":[[[6.043073,50.128052],[6.242751,49.902226],[6.18632,49.463803],[5.897759,49.442667],[5.674052,49.529484],[5.782417,50.090328],[6.043073,50.128052]]]}}, -{"type":"Feature","id":"LVA","properties":{"name":"Latvia"},"geometry":{"type":"Polygon","coordinates":[[[21.0558,56.031076],[21.090424,56.783873],[21.581866,57.411871],[22.524341,57.753374],[23.318453,57.006236],[24.12073,57.025693],[24.312863,57.793424],[25.164594,57.970157],[25.60281,57.847529],[26.463532,57.476389],[27.288185,57.474528],[27.770016,57.244258],[27.855282,56.759326],[28.176709,56.16913],[27.10246,55.783314],[26.494331,55.615107],[25.533047,56.100297],[25.000934,56.164531],[24.860684,56.372528],[23.878264,56.273671],[22.201157,56.337802],[21.0558,56.031076]]]}}, -{"type":"Feature","id":"MAR","properties":{"name":"Morocco"},"geometry":{"type":"Polygon","coordinates":[[[-5.193863,35.755182],[-4.591006,35.330712],[-3.640057,35.399855],[-2.604306,35.179093],[-2.169914,35.168396],[-1.792986,34.527919],[-1.733455,33.919713],[-1.388049,32.864015],[-1.124551,32.651522],[-1.307899,32.262889],[-2.616605,32.094346],[-3.06898,31.724498],[-3.647498,31.637294],[-3.690441,30.896952],[-4.859646,30.501188],[-5.242129,30.000443],[-6.060632,29.7317],[-7.059228,29.579228],[-8.674116,28.841289],[-8.66559,27.656426],[-8.817809,27.656426],[-8.817828,27.656426],[-8.794884,27.120696],[-9.413037,27.088476],[-9.735343,26.860945],[-10.189424,26.860945],[-10.551263,26.990808],[-11.392555,26.883424],[-11.71822,26.104092],[-12.030759,26.030866],[-12.500963,24.770116],[-13.89111,23.691009],[-14.221168,22.310163],[-14.630833,21.86094],[-14.750955,21.5006],[-17.002962,21.420734],[-17.020428,21.42231],[-16.973248,21.885745],[-16.589137,22.158234],[-16.261922,22.67934],[-16.326414,23.017768],[-15.982611,23.723358],[-15.426004,24.359134],[-15.089332,24.520261],[-14.824645,25.103533],[-14.800926,25.636265],[-14.43994,26.254418],[-13.773805,26.618892],[-13.139942,27.640148],[-13.121613,27.654148],[-12.618837,28.038186],[-11.688919,28.148644],[-10.900957,28.832142],[-10.399592,29.098586],[-9.564811,29.933574],[-9.814718,31.177736],[-9.434793,32.038096],[-9.300693,32.564679],[-8.657476,33.240245],[-7.654178,33.697065],[-6.912544,34.110476],[-6.244342,35.145865],[-5.929994,35.759988],[-5.193863,35.755182]]]}}, -{"type":"Feature","id":"MDA","properties":{"name":"Moldova"},"geometry":{"type":"Polygon","coordinates":[[[26.619337,48.220726],[26.857824,48.368211],[27.522537,48.467119],[28.259547,48.155562],[28.670891,48.118149],[29.122698,47.849095],[29.050868,47.510227],[29.415135,47.346645],[29.559674,46.928583],[29.908852,46.674361],[29.83821,46.525326],[30.024659,46.423937],[29.759972,46.349988],[29.170654,46.379262],[29.072107,46.517678],[28.862972,46.437889],[28.933717,46.25883],[28.659987,45.939987],[28.485269,45.596907],[28.233554,45.488283],[28.054443,45.944586],[28.160018,46.371563],[28.12803,46.810476],[27.551166,47.405117],[27.233873,47.826771],[26.924176,48.123264],[26.619337,48.220726]]]}}, -{"type":"Feature","id":"MDG","properties":{"name":"Madagascar"},"geometry":{"type":"Polygon","coordinates":[[[49.543519,-12.469833],[49.808981,-12.895285],[50.056511,-13.555761],[50.217431,-14.758789],[50.476537,-15.226512],[50.377111,-15.706069],[50.200275,-16.000263],[49.860606,-15.414253],[49.672607,-15.710204],[49.863344,-16.451037],[49.774564,-16.875042],[49.498612,-17.106036],[49.435619,-17.953064],[49.041792,-19.118781],[48.548541,-20.496888],[47.930749,-22.391501],[47.547723,-23.781959],[47.095761,-24.94163],[46.282478,-25.178463],[45.409508,-25.601434],[44.833574,-25.346101],[44.03972,-24.988345],[43.763768,-24.460677],[43.697778,-23.574116],[43.345654,-22.776904],[43.254187,-22.057413],[43.433298,-21.336475],[43.893683,-21.163307],[43.89637,-20.830459],[44.374325,-20.072366],[44.464397,-19.435454],[44.232422,-18.961995],[44.042976,-18.331387],[43.963084,-17.409945],[44.312469,-16.850496],[44.446517,-16.216219],[44.944937,-16.179374],[45.502732,-15.974373],[45.872994,-15.793454],[46.312243,-15.780018],[46.882183,-15.210182],[47.70513,-14.594303],[48.005215,-14.091233],[47.869047,-13.663869],[48.293828,-13.784068],[48.84506,-13.089175],[48.863509,-12.487868],[49.194651,-12.040557],[49.543519,-12.469833]]]}}, -{"type":"Feature","id":"MEX","properties":{"name":"Mexico"},"geometry":{"type":"Polygon","coordinates":[[[-97.140008,25.869997],[-97.528072,24.992144],[-97.702946,24.272343],[-97.776042,22.93258],[-97.872367,22.444212],[-97.699044,21.898689],[-97.38896,21.411019],[-97.189333,20.635433],[-96.525576,19.890931],[-96.292127,19.320371],[-95.900885,18.828024],[-94.839063,18.562717],[-94.42573,18.144371],[-93.548651,18.423837],[-92.786114,18.524839],[-92.037348,18.704569],[-91.407903,18.876083],[-90.77187,19.28412],[-90.53359,19.867418],[-90.451476,20.707522],[-90.278618,20.999855],[-89.601321,21.261726],[-88.543866,21.493675],[-87.658417,21.458846],[-87.05189,21.543543],[-86.811982,21.331515],[-86.845908,20.849865],[-87.383291,20.255405],[-87.621054,19.646553],[-87.43675,19.472403],[-87.58656,19.04013],[-87.837191,18.259816],[-88.090664,18.516648],[-88.300031,18.499982],[-88.490123,18.486831],[-88.848344,17.883198],[-89.029857,18.001511],[-89.150909,17.955468],[-89.14308,17.808319],[-90.067934,17.819326],[-91.00152,17.817595],[-91.002269,17.254658],[-91.453921,17.252177],[-91.08167,16.918477],[-90.711822,16.687483],[-90.600847,16.470778],[-90.438867,16.41011],[-90.464473,16.069562],[-91.74796,16.066565],[-92.229249,15.251447],[-92.087216,15.064585],[-92.20323,14.830103],[-92.22775,14.538829],[-93.359464,15.61543],[-93.875169,15.940164],[-94.691656,16.200975],[-95.250227,16.128318],[-96.053382,15.752088],[-96.557434,15.653515],[-97.263592,15.917065],[-98.01303,16.107312],[-98.947676,16.566043],[-99.697397,16.706164],[-100.829499,17.171071],[-101.666089,17.649026],[-101.918528,17.91609],[-102.478132,17.975751],[-103.50099,18.292295],[-103.917527,18.748572],[-104.99201,19.316134],[-105.493038,19.946767],[-105.731396,20.434102],[-105.397773,20.531719],[-105.500661,20.816895],[-105.270752,21.076285],[-105.265817,21.422104],[-105.603161,21.871146],[-105.693414,22.26908],[-106.028716,22.773752],[-106.90998,23.767774],[-107.915449,24.548915],[-108.401905,25.172314],[-109.260199,25.580609],[-109.444089,25.824884],[-109.291644,26.442934],[-109.801458,26.676176],[-110.391732,27.162115],[-110.641019,27.859876],[-111.178919,27.941241],[-111.759607,28.467953],[-112.228235,28.954409],[-112.271824,29.266844],[-112.809594,30.021114],[-113.163811,30.786881],[-113.148669,31.170966],[-113.871881,31.567608],[-114.205737,31.524045],[-114.776451,31.799532],[-114.9367,31.393485],[-114.771232,30.913617],[-114.673899,30.162681],[-114.330974,29.750432],[-113.588875,29.061611],[-113.424053,28.826174],[-113.271969,28.754783],[-113.140039,28.411289],[-112.962298,28.42519],[-112.761587,27.780217],[-112.457911,27.525814],[-112.244952,27.171727],[-111.616489,26.662817],[-111.284675,25.73259],[-110.987819,25.294606],[-110.710007,24.826004],[-110.655049,24.298595],[-110.172856,24.265548],[-109.771847,23.811183],[-109.409104,23.364672],[-109.433392,23.185588],[-109.854219,22.818272],[-110.031392,22.823078],[-110.295071,23.430973],[-110.949501,24.000964],[-111.670568,24.484423],[-112.182036,24.738413],[-112.148989,25.470125],[-112.300711,26.012004],[-112.777297,26.32196],[-113.464671,26.768186],[-113.59673,26.63946],[-113.848937,26.900064],[-114.465747,27.14209],[-115.055142,27.722727],[-114.982253,27.7982],[-114.570366,27.741485],[-114.199329,28.115003],[-114.162018,28.566112],[-114.931842,29.279479],[-115.518654,29.556362],[-115.887365,30.180794],[-116.25835,30.836464],[-116.721526,31.635744],[-117.12776,32.53534],[-115.99135,32.61239],[-114.72139,32.72083],[-114.815,32.52528],[-113.30498,32.03914],[-111.02361,31.33472],[-109.035,31.34194],[-108.24194,31.34222],[-108.24,31.754854],[-106.50759,31.75452],[-106.1429,31.39995],[-105.63159,31.08383],[-105.03737,30.64402],[-104.70575,30.12173],[-104.45697,29.57196],[-103.94,29.27],[-103.11,28.97],[-102.48,29.76],[-101.6624,29.7793],[-100.9576,29.38071],[-100.45584,28.69612],[-100.11,28.11],[-99.52,27.54],[-99.3,26.84],[-99.02,26.37],[-98.24,26.06],[-97.53,25.84],[-97.140008,25.869997]]]}}, -{"type":"Feature","id":"MKD","properties":{"name":"Macedonia"},"geometry":{"type":"Polygon","coordinates":[[[20.59023,41.85541],[20.71731,41.84711],[20.76216,42.05186],[21.3527,42.2068],[21.576636,42.245224],[21.91708,42.30364],[22.380526,42.32026],[22.881374,41.999297],[22.952377,41.337994],[22.76177,41.3048],[22.597308,41.130487],[22.055378,41.149866],[21.674161,40.931275],[21.02004,40.842727],[20.60518,41.08622],[20.46315,41.51509],[20.59023,41.85541]]]}}, -{"type":"Feature","id":"MLI","properties":{"name":"Mali"},"geometry":{"type":"Polygon","coordinates":[[[-12.17075,14.616834],[-11.834208,14.799097],[-11.666078,15.388208],[-11.349095,15.411256],[-10.650791,15.132746],[-10.086846,15.330486],[-9.700255,15.264107],[-9.550238,15.486497],[-5.537744,15.50169],[-5.315277,16.201854],[-5.488523,16.325102],[-5.971129,20.640833],[-6.453787,24.956591],[-4.923337,24.974574],[-1.550055,22.792666],[1.823228,20.610809],[2.060991,20.142233],[2.683588,19.85623],[3.146661,19.693579],[3.158133,19.057364],[4.267419,19.155265],[4.27021,16.852227],[3.723422,16.184284],[3.638259,15.56812],[2.749993,15.409525],[1.385528,15.323561],[1.015783,14.968182],[0.374892,14.928908],[-0.266257,14.924309],[-0.515854,15.116158],[-1.066363,14.973815],[-2.001035,14.559008],[-2.191825,14.246418],[-2.967694,13.79815],[-3.103707,13.541267],[-3.522803,13.337662],[-4.006391,13.472485],[-4.280405,13.228444],[-4.427166,12.542646],[-5.220942,11.713859],[-5.197843,11.375146],[-5.470565,10.95127],[-5.404342,10.370737],[-5.816926,10.222555],[-6.050452,10.096361],[-6.205223,10.524061],[-6.493965,10.411303],[-6.666461,10.430811],[-6.850507,10.138994],[-7.622759,10.147236],[-7.89959,10.297382],[-8.029944,10.206535],[-8.335377,10.494812],[-8.282357,10.792597],[-8.407311,10.909257],[-8.620321,10.810891],[-8.581305,11.136246],[-8.376305,11.393646],[-8.786099,11.812561],[-8.905265,12.088358],[-9.127474,12.30806],[-9.327616,12.334286],[-9.567912,12.194243],[-9.890993,12.060479],[-10.165214,11.844084],[-10.593224,11.923975],[-10.87083,12.177887],[-11.036556,12.211245],[-11.297574,12.077971],[-11.456169,12.076834],[-11.513943,12.442988],[-11.467899,12.754519],[-11.553398,13.141214],[-11.927716,13.422075],[-12.124887,13.994727],[-12.17075,14.616834]]]}}, -{"type":"Feature","id":"MLT","properties":{"name":"Malta"},"geometry":{"type":"MultiPolygon","coordinates":[[[[14.566171,35.852721],[14.532684,35.820191],[14.436463,35.821664],[14.352334,35.872281],[14.3513,35.978399],[14.448348,35.957444],[14.537025,35.886285],[14.566171,35.852721]]],[[[14.313473,36.027569],[14.253632,36.012143],[14.194204,36.042245],[14.180354,36.060383],[14.263243,36.075809],[14.303758,36.062295],[14.320914,36.03625],[14.313473,36.027569]]]]}}, -{"type":"Feature","id":"MMR","properties":{"name":"Myanmar"},"geometry":{"type":"Polygon","coordinates":[[[99.543309,20.186598],[98.959676,19.752981],[98.253724,19.708203],[97.797783,18.62708],[97.375896,18.445438],[97.859123,17.567946],[98.493761,16.837836],[98.903348,16.177824],[98.537376,15.308497],[98.192074,15.123703],[98.430819,14.622028],[99.097755,13.827503],[99.212012,13.269294],[99.196354,12.804748],[99.587286,11.892763],[99.038121,10.960546],[98.553551,9.93296],[98.457174,10.675266],[98.764546,11.441292],[98.428339,12.032987],[98.509574,13.122378],[98.103604,13.64046],[97.777732,14.837286],[97.597072,16.100568],[97.16454,16.928734],[96.505769,16.427241],[95.369352,15.71439],[94.808405,15.803454],[94.188804,16.037936],[94.533486,17.27724],[94.324817,18.213514],[93.540988,19.366493],[93.663255,19.726962],[93.078278,19.855145],[92.368554,20.670883],[92.303234,21.475485],[92.652257,21.324048],[92.672721,22.041239],[93.166128,22.27846],[93.060294,22.703111],[93.286327,23.043658],[93.325188,24.078556],[94.106742,23.850741],[94.552658,24.675238],[94.603249,25.162495],[95.155153,26.001307],[95.124768,26.573572],[96.419366,27.264589],[97.133999,27.083774],[97.051989,27.699059],[97.402561,27.882536],[97.327114,28.261583],[97.911988,28.335945],[98.246231,27.747221],[98.68269,27.508812],[98.712094,26.743536],[98.671838,25.918703],[97.724609,25.083637],[97.60472,23.897405],[98.660262,24.063286],[98.898749,23.142722],[99.531992,22.949039],[99.240899,22.118314],[99.983489,21.742937],[100.416538,21.558839],[101.150033,21.849984],[101.180005,21.436573],[100.329101,20.786122],[100.115988,20.41785],[99.543309,20.186598]]]}}, -{"type":"Feature","id":"MNE","properties":{"name":"Montenegro"},"geometry":{"type":"Polygon","coordinates":[[[19.801613,42.500093],[19.738051,42.688247],[19.30449,42.19574],[19.37177,41.87755],[19.16246,41.95502],[18.88214,42.28151],[18.45,42.48],[18.56,42.65],[18.70648,43.20011],[19.03165,43.43253],[19.21852,43.52384],[19.48389,43.35229],[19.63,43.21378],[19.95857,43.10604],[20.3398,42.89852],[20.25758,42.81275],[20.0707,42.58863],[19.801613,42.500093]]]}}, -{"type":"Feature","id":"MNG","properties":{"name":"Mongolia"},"geometry":{"type":"Polygon","coordinates":[[[87.751264,49.297198],[88.805567,49.470521],[90.713667,50.331812],[92.234712,50.802171],[93.104219,50.49529],[94.147566,50.480537],[94.815949,50.013433],[95.814028,49.977467],[97.259728,49.726061],[98.231762,50.422401],[97.82574,51.010995],[98.861491,52.047366],[99.981732,51.634006],[100.88948,51.516856],[102.065223,51.259921],[102.255909,50.510561],[103.676545,50.089966],[104.621552,50.275329],[105.886591,50.406019],[106.888804,50.274296],[107.868176,49.793705],[108.475167,49.282548],[109.402449,49.292961],[110.662011,49.130128],[111.581231,49.377968],[112.89774,49.543565],[114.362456,50.248303],[114.96211,50.140247],[115.485695,49.805177],[116.678801,49.888531],[116.191802,49.134598],[115.485282,48.135383],[115.742837,47.726545],[116.308953,47.85341],[117.295507,47.697709],[118.064143,48.06673],[118.866574,47.74706],[119.772824,47.048059],[119.66327,46.69268],[118.874326,46.805412],[117.421701,46.672733],[116.717868,46.388202],[115.985096,45.727235],[114.460332,45.339817],[113.463907,44.808893],[112.436062,45.011646],[111.873306,45.102079],[111.348377,44.457442],[111.667737,44.073176],[111.829588,43.743118],[111.129682,43.406834],[110.412103,42.871234],[109.243596,42.519446],[107.744773,42.481516],[106.129316,42.134328],[104.964994,41.59741],[104.522282,41.908347],[103.312278,41.907468],[101.83304,42.514873],[100.845866,42.663804],[99.515817,42.524691],[97.451757,42.74889],[96.349396,42.725635],[95.762455,43.319449],[95.306875,44.241331],[94.688929,44.352332],[93.480734,44.975472],[92.133891,45.115076],[90.94554,45.286073],[90.585768,45.719716],[90.970809,46.888146],[90.280826,47.693549],[88.854298,48.069082],[88.013832,48.599463],[87.751264,49.297198]]]}}, -{"type":"Feature","id":"MOZ","properties":{"name":"Mozambique"},"geometry":{"type":"Polygon","coordinates":[[[34.559989,-11.52002],[35.312398,-11.439146],[36.514082,-11.720938],[36.775151,-11.594537],[37.471284,-11.568751],[37.827645,-11.268769],[38.427557,-11.285202],[39.52103,-10.896854],[40.316589,-10.317096],[40.478387,-10.765441],[40.437253,-11.761711],[40.560811,-12.639177],[40.59962,-14.201975],[40.775475,-14.691764],[40.477251,-15.406294],[40.089264,-16.100774],[39.452559,-16.720891],[38.538351,-17.101023],[37.411133,-17.586368],[36.281279,-18.659688],[35.896497,-18.84226],[35.1984,-19.552811],[34.786383,-19.784012],[34.701893,-20.497043],[35.176127,-21.254361],[35.373428,-21.840837],[35.385848,-22.14],[35.562546,-22.09],[35.533935,-23.070788],[35.371774,-23.535359],[35.60747,-23.706563],[35.458746,-24.12261],[35.040735,-24.478351],[34.215824,-24.816314],[33.01321,-25.357573],[32.574632,-25.727318],[32.660363,-26.148584],[32.915955,-26.215867],[32.83012,-26.742192],[32.071665,-26.73382],[31.985779,-26.29178],[31.837778,-25.843332],[31.752408,-25.484284],[31.930589,-24.369417],[31.670398,-23.658969],[31.191409,-22.25151],[32.244988,-21.116489],[32.508693,-20.395292],[32.659743,-20.30429],[32.772708,-19.715592],[32.611994,-19.419383],[32.654886,-18.67209],[32.849861,-17.979057],[32.847639,-16.713398],[32.328239,-16.392074],[31.852041,-16.319417],[31.636498,-16.07199],[31.173064,-15.860944],[30.338955,-15.880839],[30.274256,-15.507787],[30.179481,-14.796099],[33.214025,-13.97186],[33.7897,-14.451831],[34.064825,-14.35995],[34.459633,-14.61301],[34.517666,-15.013709],[34.307291,-15.478641],[34.381292,-16.18356],[35.03381,-16.8013],[35.339063,-16.10744],[35.771905,-15.896859],[35.686845,-14.611046],[35.267956,-13.887834],[34.907151,-13.565425],[34.559989,-13.579998],[34.280006,-12.280025],[34.559989,-11.52002]]]}}, -{"type":"Feature","id":"MRT","properties":{"name":"Mauritania"},"geometry":{"type":"Polygon","coordinates":[[[-12.17075,14.616834],[-12.830658,15.303692],[-13.435738,16.039383],[-14.099521,16.304302],[-14.577348,16.598264],[-15.135737,16.587282],[-15.623666,16.369337],[-16.12069,16.455663],[-16.463098,16.135036],[-16.549708,16.673892],[-16.270552,17.166963],[-16.146347,18.108482],[-16.256883,19.096716],[-16.377651,19.593817],[-16.277838,20.092521],[-16.536324,20.567866],[-17.063423,20.999752],[-16.845194,21.333323],[-12.929102,21.327071],[-13.118754,22.77122],[-12.874222,23.284832],[-11.937224,23.374594],[-11.969419,25.933353],[-8.687294,25.881056],[-8.6844,27.395744],[-4.923337,24.974574],[-6.453787,24.956591],[-5.971129,20.640833],[-5.488523,16.325102],[-5.315277,16.201854],[-5.537744,15.50169],[-9.550238,15.486497],[-9.700255,15.264107],[-10.086846,15.330486],[-10.650791,15.132746],[-11.349095,15.411256],[-11.666078,15.388208],[-11.834208,14.799097],[-12.17075,14.616834]]]}}, -{"type":"Feature","id":"MWI","properties":{"name":"Malawi"},"geometry":{"type":"Polygon","coordinates":[[[34.559989,-11.52002],[34.280006,-12.280025],[34.559989,-13.579998],[34.907151,-13.565425],[35.267956,-13.887834],[35.686845,-14.611046],[35.771905,-15.896859],[35.339063,-16.10744],[35.03381,-16.8013],[34.381292,-16.18356],[34.307291,-15.478641],[34.517666,-15.013709],[34.459633,-14.61301],[34.064825,-14.35995],[33.7897,-14.451831],[33.214025,-13.97186],[32.688165,-13.712858],[32.991764,-12.783871],[33.306422,-12.435778],[33.114289,-11.607198],[33.31531,-10.79655],[33.485688,-10.525559],[33.231388,-9.676722],[32.759375,-9.230599],[33.739729,-9.417151],[33.940838,-9.693674],[34.280006,-10.16],[34.559989,-11.52002]]]}}, -{"type":"Feature","id":"MYS","properties":{"name":"Malaysia"},"geometry":{"type":"MultiPolygon","coordinates":[[[[101.075516,6.204867],[101.154219,5.691384],[101.814282,5.810808],[102.141187,6.221636],[102.371147,6.128205],[102.961705,5.524495],[103.381215,4.855001],[103.438575,4.181606],[103.332122,3.726698],[103.429429,3.382869],[103.502448,2.791019],[103.854674,2.515454],[104.247932,1.631141],[104.228811,1.293048],[103.519707,1.226334],[102.573615,1.967115],[101.390638,2.760814],[101.27354,3.270292],[100.695435,3.93914],[100.557408,4.76728],[100.196706,5.312493],[100.30626,6.040562],[100.085757,6.464489],[100.259596,6.642825],[101.075516,6.204867]]],[[[118.618321,4.478202],[117.882035,4.137551],[117.015214,4.306094],[115.865517,4.306559],[115.519078,3.169238],[115.134037,2.821482],[114.621355,1.430688],[113.80585,1.217549],[112.859809,1.49779],[112.380252,1.410121],[111.797548,0.904441],[111.159138,0.976478],[110.514061,0.773131],[109.830227,1.338136],[109.66326,2.006467],[110.396135,1.663775],[111.168853,1.850637],[111.370081,2.697303],[111.796928,2.885897],[112.995615,3.102395],[113.712935,3.893509],[114.204017,4.525874],[114.659596,4.007637],[114.869557,4.348314],[115.347461,4.316636],[115.4057,4.955228],[115.45071,5.44773],[116.220741,6.143191],[116.725103,6.924771],[117.129626,6.928053],[117.643393,6.422166],[117.689075,5.98749],[118.347691,5.708696],[119.181904,5.407836],[119.110694,5.016128],[118.439727,4.966519],[118.618321,4.478202]]]]}}, -{"type":"Feature","id":"NAM","properties":{"name":"Namibia"},"geometry":{"type":"Polygon","coordinates":[[[16.344977,-28.576705],[15.601818,-27.821247],[15.210472,-27.090956],[14.989711,-26.117372],[14.743214,-25.39292],[14.408144,-23.853014],[14.385717,-22.656653],[14.257714,-22.111208],[13.868642,-21.699037],[13.352498,-20.872834],[12.826845,-19.673166],[12.608564,-19.045349],[11.794919,-18.069129],[11.734199,-17.301889],[12.215461,-17.111668],[12.814081,-16.941343],[13.462362,-16.971212],[14.058501,-17.423381],[14.209707,-17.353101],[18.263309,-17.309951],[18.956187,-17.789095],[21.377176,-17.930636],[23.215048,-17.523116],[24.033862,-17.295843],[24.682349,-17.353411],[25.07695,-17.578823],[25.084443,-17.661816],[24.520705,-17.887125],[24.217365,-17.889347],[23.579006,-18.281261],[23.196858,-17.869038],[21.65504,-18.219146],[20.910641,-18.252219],[20.881134,-21.814327],[19.895458,-21.849157],[19.895768,-24.76779],[19.894734,-28.461105],[19.002127,-28.972443],[18.464899,-29.045462],[17.836152,-28.856378],[17.387497,-28.783514],[17.218929,-28.355943],[16.824017,-28.082162],[16.344977,-28.576705]]]}}, -{"type":"Feature","id":"NCL","properties":{"name":"New Caledonia"},"geometry":{"type":"Polygon","coordinates":[[[165.77999,-21.080005],[166.599991,-21.700019],[167.120011,-22.159991],[166.740035,-22.399976],[166.189732,-22.129708],[165.474375,-21.679607],[164.829815,-21.14982],[164.167995,-20.444747],[164.029606,-20.105646],[164.459967,-20.120012],[165.020036,-20.459991],[165.460009,-20.800022],[165.77999,-21.080005]]]}}, -{"type":"Feature","id":"NER","properties":{"name":"Niger"},"geometry":{"type":"Polygon","coordinates":[[[2.154474,11.94015],[2.177108,12.625018],[1.024103,12.851826],[0.993046,13.33575],[0.429928,13.988733],[0.295646,14.444235],[0.374892,14.928908],[1.015783,14.968182],[1.385528,15.323561],[2.749993,15.409525],[3.638259,15.56812],[3.723422,16.184284],[4.27021,16.852227],[4.267419,19.155265],[5.677566,19.601207],[8.572893,21.565661],[11.999506,23.471668],[13.581425,23.040506],[14.143871,22.491289],[14.8513,22.86295],[15.096888,21.308519],[15.471077,21.048457],[15.487148,20.730415],[15.903247,20.387619],[15.685741,19.95718],[15.300441,17.92795],[15.247731,16.627306],[13.972202,15.684366],[13.540394,14.367134],[13.956699,13.996691],[13.954477,13.353449],[14.595781,13.330427],[14.495787,12.859396],[14.213531,12.802035],[14.181336,12.483657],[13.995353,12.461565],[13.318702,13.556356],[13.083987,13.596147],[12.302071,13.037189],[11.527803,13.32898],[10.989593,13.387323],[10.701032,13.246918],[10.114814,13.277252],[9.524928,12.851102],[9.014933,12.826659],[7.804671,13.343527],[7.330747,13.098038],[6.820442,13.115091],[6.445426,13.492768],[5.443058,13.865924],[4.368344,13.747482],[4.107946,13.531216],[3.967283,12.956109],[3.680634,12.552903],[3.61118,11.660167],[2.848643,12.235636],[2.490164,12.233052],[2.154474,11.94015]]]}}, -{"type":"Feature","id":"NGA","properties":{"name":"Nigeria"},"geometry":{"type":"Polygon","coordinates":[[[8.500288,4.771983],[7.462108,4.412108],[7.082596,4.464689],[6.698072,4.240594],[5.898173,4.262453],[5.362805,4.887971],[5.033574,5.611802],[4.325607,6.270651],[3.57418,6.2583],[2.691702,6.258817],[2.749063,7.870734],[2.723793,8.506845],[2.912308,9.137608],[3.220352,9.444153],[3.705438,10.06321],[3.60007,10.332186],[3.797112,10.734746],[3.572216,11.327939],[3.61118,11.660167],[3.680634,12.552903],[3.967283,12.956109],[4.107946,13.531216],[4.368344,13.747482],[5.443058,13.865924],[6.445426,13.492768],[6.820442,13.115091],[7.330747,13.098038],[7.804671,13.343527],[9.014933,12.826659],[9.524928,12.851102],[10.114814,13.277252],[10.701032,13.246918],[10.989593,13.387323],[11.527803,13.32898],[12.302071,13.037189],[13.083987,13.596147],[13.318702,13.556356],[13.995353,12.461565],[14.181336,12.483657],[14.577178,12.085361],[14.468192,11.904752],[14.415379,11.572369],[13.57295,10.798566],[13.308676,10.160362],[13.1676,9.640626],[12.955468,9.417772],[12.753672,8.717763],[12.218872,8.305824],[12.063946,7.799808],[11.839309,7.397042],[11.745774,6.981383],[11.058788,6.644427],[10.497375,7.055358],[10.118277,7.03877],[9.522706,6.453482],[9.233163,6.444491],[8.757533,5.479666],[8.500288,4.771983]]]}}, -{"type":"Feature","id":"NIC","properties":{"name":"Nicaragua"},"geometry":{"type":"Polygon","coordinates":[[[-85.71254,11.088445],[-86.058488,11.403439],[-86.52585,11.806877],[-86.745992,12.143962],[-87.167516,12.458258],[-87.668493,12.90991],[-87.557467,13.064552],[-87.392386,12.914018],[-87.316654,12.984686],[-87.005769,13.025794],[-86.880557,13.254204],[-86.733822,13.263093],[-86.755087,13.754845],[-86.520708,13.778487],[-86.312142,13.771356],[-86.096264,14.038187],[-85.801295,13.836055],[-85.698665,13.960078],[-85.514413,14.079012],[-85.165365,14.35437],[-85.148751,14.560197],[-85.052787,14.551541],[-84.924501,14.790493],[-84.820037,14.819587],[-84.649582,14.666805],[-84.449336,14.621614],[-84.228342,14.748764],[-83.975721,14.749436],[-83.628585,14.880074],[-83.489989,15.016267],[-83.147219,14.995829],[-83.233234,14.899866],[-83.284162,14.676624],[-83.182126,14.310703],[-83.4125,13.970078],[-83.519832,13.567699],[-83.552207,13.127054],[-83.498515,12.869292],[-83.473323,12.419087],[-83.626104,12.32085],[-83.719613,11.893124],[-83.650858,11.629032],[-83.85547,11.373311],[-83.808936,11.103044],[-83.655612,10.938764],[-83.895054,10.726839],[-84.190179,10.79345],[-84.355931,10.999226],[-84.673069,11.082657],[-84.903003,10.952303],[-85.561852,11.217119],[-85.71254,11.088445]]]}}, -{"type":"Feature","id":"NLD","properties":{"name":"Netherlands"},"geometry":{"type":"Polygon","coordinates":[[[6.074183,53.510403],[6.90514,53.482162],[7.092053,53.144043],[6.84287,52.22844],[6.589397,51.852029],[5.988658,51.851616],[6.156658,50.803721],[5.606976,51.037298],[4.973991,51.475024],[4.047071,51.267259],[3.314971,51.345755],[3.830289,51.620545],[4.705997,53.091798],[6.074183,53.510403]]]}}, -{"type":"Feature","id":"NOR","properties":{"name":"Norway"},"geometry":{"type":"MultiPolygon","coordinates":[[[[28.165547,71.185474],[31.293418,70.453788],[30.005435,70.186259],[31.101079,69.55808],[29.399581,69.156916],[28.59193,69.064777],[29.015573,69.766491],[27.732292,70.164193],[26.179622,69.825299],[25.689213,69.092114],[24.735679,68.649557],[23.66205,68.891247],[22.356238,68.841741],[21.244936,69.370443],[20.645593,69.106247],[20.025269,69.065139],[19.87856,68.407194],[17.993868,68.567391],[17.729182,68.010552],[16.768879,68.013937],[16.108712,67.302456],[15.108411,66.193867],[13.55569,64.787028],[13.919905,64.445421],[13.571916,64.049114],[12.579935,64.066219],[11.930569,63.128318],[11.992064,61.800362],[12.631147,61.293572],[12.300366,60.117933],[11.468272,59.432393],[11.027369,58.856149],[10.356557,59.469807],[8.382,58.313288],[7.048748,58.078884],[5.665835,58.588155],[5.308234,59.663232],[4.992078,61.970998],[5.9129,62.614473],[8.553411,63.454008],[10.527709,64.486038],[12.358347,65.879726],[14.761146,67.810642],[16.435927,68.563205],[19.184028,69.817444],[21.378416,70.255169],[23.023742,70.202072],[24.546543,71.030497],[26.37005,70.986262],[28.165547,71.185474]]],[[[24.72412,77.85385],[22.49032,77.44493],[20.72601,77.67704],[21.41611,77.93504],[20.8119,78.25463],[22.88426,78.45494],[23.28134,78.07954],[24.72412,77.85385]]],[[[18.25183,79.70175],[21.54383,78.95611],[19.02737,78.5626],[18.47172,77.82669],[17.59441,77.63796],[17.1182,76.80941],[15.91315,76.77045],[13.76259,77.38035],[14.66956,77.73565],[13.1706,78.02493],[11.22231,78.8693],[10.44453,79.65239],[13.17077,80.01046],[13.71852,79.66039],[15.14282,79.67431],[15.52255,80.01608],[16.99085,80.05086],[18.25183,79.70175]]],[[[25.447625,80.40734],[27.407506,80.056406],[25.924651,79.517834],[23.024466,79.400012],[20.075188,79.566823],[19.897266,79.842362],[18.462264,79.85988],[17.368015,80.318896],[20.455992,80.598156],[21.907945,80.357679],[22.919253,80.657144],[25.447625,80.40734]]]]}}, -{"type":"Feature","id":"NPL","properties":{"name":"Nepal"},"geometry":{"type":"Polygon","coordinates":[[[88.120441,27.876542],[88.043133,27.445819],[88.174804,26.810405],[88.060238,26.414615],[87.227472,26.397898],[86.024393,26.630985],[85.251779,26.726198],[84.675018,27.234901],[83.304249,27.364506],[81.999987,27.925479],[81.057203,28.416095],[80.088425,28.79447],[80.476721,29.729865],[81.111256,30.183481],[81.525804,30.422717],[82.327513,30.115268],[83.337115,29.463732],[83.898993,29.320226],[84.23458,28.839894],[85.011638,28.642774],[85.82332,28.203576],[86.954517,27.974262],[88.120441,27.876542]]]}}, -{"type":"Feature","id":"NZL","properties":{"name":"New Zealand"},"geometry":{"type":"MultiPolygon","coordinates":[[[[173.020375,-40.919052],[173.247234,-41.331999],[173.958405,-40.926701],[174.247587,-41.349155],[174.248517,-41.770008],[173.876447,-42.233184],[173.22274,-42.970038],[172.711246,-43.372288],[173.080113,-43.853344],[172.308584,-43.865694],[171.452925,-44.242519],[171.185138,-44.897104],[170.616697,-45.908929],[169.831422,-46.355775],[169.332331,-46.641235],[168.411354,-46.619945],[167.763745,-46.290197],[166.676886,-46.219917],[166.509144,-45.852705],[167.046424,-45.110941],[168.303763,-44.123973],[168.949409,-43.935819],[169.667815,-43.555326],[170.52492,-43.031688],[171.12509,-42.512754],[171.569714,-41.767424],[171.948709,-41.514417],[172.097227,-40.956104],[172.79858,-40.493962],[173.020375,-40.919052]]],[[[174.612009,-36.156397],[175.336616,-37.209098],[175.357596,-36.526194],[175.808887,-36.798942],[175.95849,-37.555382],[176.763195,-37.881253],[177.438813,-37.961248],[178.010354,-37.579825],[178.517094,-37.695373],[178.274731,-38.582813],[177.97046,-39.166343],[177.206993,-39.145776],[176.939981,-39.449736],[177.032946,-39.879943],[176.885824,-40.065978],[176.508017,-40.604808],[176.01244,-41.289624],[175.239567,-41.688308],[175.067898,-41.425895],[174.650973,-41.281821],[175.22763,-40.459236],[174.900157,-39.908933],[173.824047,-39.508854],[173.852262,-39.146602],[174.574802,-38.797683],[174.743474,-38.027808],[174.697017,-37.381129],[174.292028,-36.711092],[174.319004,-36.534824],[173.840997,-36.121981],[173.054171,-35.237125],[172.636005,-34.529107],[173.007042,-34.450662],[173.551298,-35.006183],[174.32939,-35.265496],[174.612009,-36.156397]]]]}}, -{"type":"Feature","id":"OMN","properties":{"name":"Oman"},"geometry":{"type":"MultiPolygon","coordinates":[[[[58.861141,21.114035],[58.487986,20.428986],[58.034318,20.481437],[57.826373,20.243002],[57.665762,19.736005],[57.7887,19.06757],[57.694391,18.94471],[57.234264,18.947991],[56.609651,18.574267],[56.512189,18.087113],[56.283521,17.876067],[55.661492,17.884128],[55.269939,17.632309],[55.2749,17.228354],[54.791002,16.950697],[54.239253,17.044981],[53.570508,16.707663],[53.108573,16.651051],[52.782184,17.349742],[52.00001,19.000003],[54.999982,19.999994],[55.666659,22.000001],[55.208341,22.70833],[55.234489,23.110993],[55.525841,23.524869],[55.528632,23.933604],[55.981214,24.130543],[55.804119,24.269604],[55.886233,24.920831],[56.396847,24.924732],[56.84514,24.241673],[57.403453,23.878594],[58.136948,23.747931],[58.729211,23.565668],[59.180502,22.992395],[59.450098,22.660271],[59.80806,22.533612],[59.806148,22.310525],[59.442191,21.714541],[59.282408,21.433886],[58.861141,21.114035]]],[[[56.391421,25.895991],[56.261042,25.714606],[56.070821,26.055464],[56.362017,26.395934],[56.485679,26.309118],[56.391421,25.895991]]]]}}, -{"type":"Feature","id":"PAK","properties":{"name":"Pakistan"},"geometry":{"type":"Polygon","coordinates":[[[75.158028,37.133031],[75.896897,36.666806],[76.192848,35.898403],[77.837451,35.49401],[76.871722,34.653544],[75.757061,34.504923],[74.240203,34.748887],[73.749948,34.317699],[74.104294,33.441473],[74.451559,32.7649],[75.258642,32.271105],[74.405929,31.692639],[74.42138,30.979815],[73.450638,29.976413],[72.823752,28.961592],[71.777666,27.91318],[70.616496,27.989196],[69.514393,26.940966],[70.168927,26.491872],[70.282873,25.722229],[70.844699,25.215102],[71.04324,24.356524],[68.842599,24.359134],[68.176645,23.691965],[67.443667,23.944844],[67.145442,24.663611],[66.372828,25.425141],[64.530408,25.237039],[62.905701,25.218409],[61.497363,25.078237],[61.874187,26.239975],[63.316632,26.756532],[63.233898,27.217047],[62.755426,27.378923],[62.72783,28.259645],[61.771868,28.699334],[61.369309,29.303276],[60.874248,29.829239],[62.549857,29.318572],[63.550261,29.468331],[64.148002,29.340819],[64.350419,29.560031],[65.046862,29.472181],[66.346473,29.887943],[66.381458,30.738899],[66.938891,31.304911],[67.683394,31.303154],[67.792689,31.58293],[68.556932,31.71331],[68.926677,31.620189],[69.317764,31.901412],[69.262522,32.501944],[69.687147,33.105499],[70.323594,33.358533],[69.930543,34.02012],[70.881803,33.988856],[71.156773,34.348911],[71.115019,34.733126],[71.613076,35.153203],[71.498768,35.650563],[71.262348,36.074388],[71.846292,36.509942],[72.920025,36.720007],[74.067552,36.836176],[74.575893,37.020841],[75.158028,37.133031]]]}}, -{"type":"Feature","id":"PAN","properties":{"name":"Panama"},"geometry":{"type":"Polygon","coordinates":[[[-77.881571,7.223771],[-78.214936,7.512255],[-78.429161,8.052041],[-78.182096,8.319182],[-78.435465,8.387705],[-78.622121,8.718124],[-79.120307,8.996092],[-79.557877,8.932375],[-79.760578,8.584515],[-80.164481,8.333316],[-80.382659,8.298409],[-80.480689,8.090308],[-80.00369,7.547524],[-80.276671,7.419754],[-80.421158,7.271572],[-80.886401,7.220541],[-81.059543,7.817921],[-81.189716,7.647906],[-81.519515,7.70661],[-81.721311,8.108963],[-82.131441,8.175393],[-82.390934,8.292362],[-82.820081,8.290864],[-82.850958,8.073823],[-82.965783,8.225028],[-82.913176,8.423517],[-82.829771,8.626295],[-82.868657,8.807266],[-82.719183,8.925709],[-82.927155,9.07433],[-82.932891,9.476812],[-82.546196,9.566135],[-82.187123,9.207449],[-82.207586,8.995575],[-81.808567,8.950617],[-81.714154,9.031955],[-81.439287,8.786234],[-80.947302,8.858504],[-80.521901,9.111072],[-79.9146,9.312765],[-79.573303,9.61161],[-79.021192,9.552931],[-79.05845,9.454565],[-78.500888,9.420459],[-78.055928,9.24773],[-77.729514,8.946844],[-77.353361,8.670505],[-77.474723,8.524286],[-77.242566,7.935278],[-77.431108,7.638061],[-77.753414,7.70984],[-77.881571,7.223771]]]}}, -{"type":"Feature","id":"PER","properties":{"name":"Peru"},"geometry":{"type":"Polygon","coordinates":[[[-69.590424,-17.580012],[-69.858444,-18.092694],[-70.372572,-18.347975],[-71.37525,-17.773799],[-71.462041,-17.363488],[-73.44453,-16.359363],[-75.237883,-15.265683],[-76.009205,-14.649286],[-76.423469,-13.823187],[-76.259242,-13.535039],[-77.106192,-12.222716],[-78.092153,-10.377712],[-79.036953,-8.386568],[-79.44592,-7.930833],[-79.760578,-7.194341],[-80.537482,-6.541668],[-81.249996,-6.136834],[-80.926347,-5.690557],[-81.410943,-4.736765],[-81.09967,-4.036394],[-80.302561,-3.404856],[-80.184015,-3.821162],[-80.469295,-4.059287],[-80.442242,-4.425724],[-80.028908,-4.346091],[-79.624979,-4.454198],[-79.205289,-4.959129],[-78.639897,-4.547784],[-78.450684,-3.873097],[-77.837905,-3.003021],[-76.635394,-2.608678],[-75.544996,-1.56161],[-75.233723,-0.911417],[-75.373223,-0.152032],[-75.106625,-0.057205],[-74.441601,-0.53082],[-74.122395,-1.002833],[-73.659504,-1.260491],[-73.070392,-2.308954],[-72.325787,-2.434218],[-71.774761,-2.16979],[-71.413646,-2.342802],[-70.813476,-2.256865],[-70.047709,-2.725156],[-70.692682,-3.742872],[-70.394044,-3.766591],[-69.893635,-4.298187],[-70.794769,-4.251265],[-70.928843,-4.401591],[-71.748406,-4.593983],[-72.891928,-5.274561],[-72.964507,-5.741251],[-73.219711,-6.089189],[-73.120027,-6.629931],[-73.724487,-6.918595],[-73.723401,-7.340999],[-73.987235,-7.52383],[-73.571059,-8.424447],[-73.015383,-9.032833],[-73.226713,-9.462213],[-72.563033,-9.520194],[-72.184891,-10.053598],[-71.302412,-10.079436],[-70.481894,-9.490118],[-70.548686,-11.009147],[-70.093752,-11.123972],[-69.529678,-10.951734],[-68.66508,-12.5613],[-68.88008,-12.899729],[-68.929224,-13.602684],[-68.948887,-14.453639],[-69.339535,-14.953195],[-69.160347,-15.323974],[-69.389764,-15.660129],[-68.959635,-16.500698],[-69.590424,-17.580012]]]}}, -{"type":"Feature","id":"PHL","properties":{"name":"Philippines"},"geometry":{"type":"MultiPolygon","coordinates":[[[[126.376814,8.414706],[126.478513,7.750354],[126.537424,7.189381],[126.196773,6.274294],[125.831421,7.293715],[125.363852,6.786485],[125.683161,6.049657],[125.396512,5.581003],[124.219788,6.161355],[123.93872,6.885136],[124.243662,7.36061],[123.610212,7.833527],[123.296071,7.418876],[122.825506,7.457375],[122.085499,6.899424],[121.919928,7.192119],[122.312359,8.034962],[122.942398,8.316237],[123.487688,8.69301],[123.841154,8.240324],[124.60147,8.514158],[124.764612,8.960409],[125.471391,8.986997],[125.412118,9.760335],[126.222714,9.286074],[126.306637,8.782487],[126.376814,8.414706]]],[[[123.982438,10.278779],[123.623183,9.950091],[123.309921,9.318269],[122.995883,9.022189],[122.380055,9.713361],[122.586089,9.981045],[122.837081,10.261157],[122.947411,10.881868],[123.49885,10.940624],[123.337774,10.267384],[124.077936,11.232726],[123.982438,10.278779]]],[[[118.504581,9.316383],[117.174275,8.3675],[117.664477,9.066889],[118.386914,9.6845],[118.987342,10.376292],[119.511496,11.369668],[119.689677,10.554291],[119.029458,10.003653],[118.504581,9.316383]]],[[[121.883548,11.891755],[122.483821,11.582187],[123.120217,11.58366],[123.100838,11.165934],[122.637714,10.741308],[122.00261,10.441017],[121.967367,10.905691],[122.03837,11.415841],[121.883548,11.891755]]],[[[125.502552,12.162695],[125.783465,11.046122],[125.011884,11.311455],[125.032761,10.975816],[125.277449,10.358722],[124.801819,10.134679],[124.760168,10.837995],[124.459101,10.88993],[124.302522,11.495371],[124.891013,11.415583],[124.87799,11.79419],[124.266762,12.557761],[125.227116,12.535721],[125.502552,12.162695]]],[[[121.527394,13.06959],[121.26219,12.20556],[120.833896,12.704496],[120.323436,13.466413],[121.180128,13.429697],[121.527394,13.06959]]],[[[121.321308,18.504065],[121.937601,18.218552],[122.246006,18.47895],[122.336957,18.224883],[122.174279,17.810283],[122.515654,17.093505],[122.252311,16.262444],[121.662786,15.931018],[121.50507,15.124814],[121.728829,14.328376],[122.258925,14.218202],[122.701276,14.336541],[123.950295,13.782131],[123.855107,13.237771],[124.181289,12.997527],[124.077419,12.536677],[123.298035,13.027526],[122.928652,13.55292],[122.671355,13.185836],[122.03465,13.784482],[121.126385,13.636687],[120.628637,13.857656],[120.679384,14.271016],[120.991819,14.525393],[120.693336,14.756671],[120.564145,14.396279],[120.070429,14.970869],[119.920929,15.406347],[119.883773,16.363704],[120.286488,16.034629],[120.390047,17.599081],[120.715867,18.505227],[121.321308,18.504065]]]]}}, -{"type":"Feature","id":"PNG","properties":{"name":"Papua New Guinea"},"geometry":{"type":"MultiPolygon","coordinates":[[[[155.880026,-6.819997],[155.599991,-6.919991],[155.166994,-6.535931],[154.729192,-5.900828],[154.514114,-5.139118],[154.652504,-5.042431],[154.759991,-5.339984],[155.062918,-5.566792],[155.547746,-6.200655],[156.019965,-6.540014],[155.880026,-6.819997]]],[[[151.982796,-5.478063],[151.459107,-5.56028],[151.30139,-5.840728],[150.754447,-6.083763],[150.241197,-6.317754],[149.709963,-6.316513],[148.890065,-6.02604],[148.318937,-5.747142],[148.401826,-5.437756],[149.298412,-5.583742],[149.845562,-5.505503],[149.99625,-5.026101],[150.139756,-5.001348],[150.236908,-5.53222],[150.807467,-5.455842],[151.089672,-5.113693],[151.647881,-4.757074],[151.537862,-4.167807],[152.136792,-4.14879],[152.338743,-4.312966],[152.318693,-4.867661],[151.982796,-5.478063]]],[[[147.191874,-7.388024],[148.084636,-8.044108],[148.734105,-9.104664],[149.306835,-9.071436],[149.266631,-9.514406],[150.038728,-9.684318],[149.738798,-9.872937],[150.801628,-10.293687],[150.690575,-10.582713],[150.028393,-10.652476],[149.78231,-10.393267],[148.923138,-10.280923],[147.913018,-10.130441],[147.135443,-9.492444],[146.567881,-8.942555],[146.048481,-8.067414],[144.744168,-7.630128],[143.897088,-7.91533],[143.286376,-8.245491],[143.413913,-8.983069],[142.628431,-9.326821],[142.068259,-9.159596],[141.033852,-9.117893],[141.017057,-5.859022],[141.00021,-2.600151],[142.735247,-3.289153],[144.583971,-3.861418],[145.27318,-4.373738],[145.829786,-4.876498],[145.981922,-5.465609],[147.648073,-6.083659],[147.891108,-6.614015],[146.970905,-6.721657],[147.191874,-7.388024]]],[[[153.140038,-4.499983],[152.827292,-4.766427],[152.638673,-4.176127],[152.406026,-3.789743],[151.953237,-3.462062],[151.384279,-3.035422],[150.66205,-2.741486],[150.939965,-2.500002],[151.479984,-2.779985],[151.820015,-2.999972],[152.239989,-3.240009],[152.640017,-3.659983],[153.019994,-3.980015],[153.140038,-4.499983]]]]}}, -{"type":"Feature","id":"POL","properties":{"name":"Poland"},"geometry":{"type":"Polygon","coordinates":[[[15.016996,51.106674],[14.607098,51.745188],[14.685026,52.089947],[14.4376,52.62485],[14.074521,52.981263],[14.353315,53.248171],[14.119686,53.757029],[14.8029,54.050706],[16.363477,54.513159],[17.622832,54.851536],[18.620859,54.682606],[18.696255,54.438719],[19.66064,54.426084],[20.892245,54.312525],[22.731099,54.327537],[23.243987,54.220567],[23.484128,53.912498],[23.527536,53.470122],[23.804935,53.089731],[23.799199,52.691099],[23.199494,52.486977],[23.508002,52.023647],[23.527071,51.578454],[24.029986,50.705407],[23.922757,50.424881],[23.426508,50.308506],[22.51845,49.476774],[22.776419,49.027395],[22.558138,49.085738],[21.607808,49.470107],[20.887955,49.328772],[20.415839,49.431453],[19.825023,49.217125],[19.320713,49.571574],[18.909575,49.435846],[18.853144,49.49623],[18.392914,49.988629],[17.649445,50.049038],[17.554567,50.362146],[16.868769,50.473974],[16.719476,50.215747],[16.176253,50.422607],[16.238627,50.697733],[15.490972,50.78473],[15.016996,51.106674]]]}}, -{"type":"Feature","id":"PRI","properties":{"name":"Puerto Rico"},"geometry":{"type":"Polygon","coordinates":[[[-66.282434,18.514762],[-65.771303,18.426679],[-65.591004,18.228035],[-65.847164,17.975906],[-66.599934,17.981823],[-67.184162,17.946553],[-67.242428,18.37446],[-67.100679,18.520601],[-66.282434,18.514762]]]}}, -{"type":"Feature","id":"PRK","properties":{"name":"North Korea"},"geometry":{"type":"Polygon","coordinates":[[[130.640016,42.395009],[130.780007,42.220007],[130.400031,42.280004],[129.965949,41.941368],[129.667362,41.601104],[129.705189,40.882828],[129.188115,40.661808],[129.0104,40.485436],[128.633368,40.189847],[127.967414,40.025413],[127.533436,39.75685],[127.50212,39.323931],[127.385434,39.213472],[127.783343,39.050898],[128.349716,38.612243],[128.205746,38.370397],[127.780035,38.304536],[127.073309,38.256115],[126.68372,37.804773],[126.237339,37.840378],[126.174759,37.749686],[125.689104,37.94001],[125.568439,37.752089],[125.27533,37.669071],[125.240087,37.857224],[124.981033,37.948821],[124.712161,38.108346],[124.985994,38.548474],[125.221949,38.665857],[125.132859,38.848559],[125.38659,39.387958],[125.321116,39.551385],[124.737482,39.660344],[124.265625,39.928493],[125.079942,40.569824],[126.182045,41.107336],[126.869083,41.816569],[127.343783,41.503152],[128.208433,41.466772],[128.052215,41.994285],[129.596669,42.424982],[129.994267,42.985387],[130.640016,42.395009]]]}}, -{"type":"Feature","id":"PRT","properties":{"name":"Portugal"},"geometry":{"type":"Polygon","coordinates":[[[-9.034818,41.880571],[-8.671946,42.134689],[-8.263857,42.280469],[-8.013175,41.790886],[-7.422513,41.792075],[-7.251309,41.918346],[-6.668606,41.883387],[-6.389088,41.381815],[-6.851127,41.111083],[-6.86402,40.330872],[-7.026413,40.184524],[-7.066592,39.711892],[-7.498632,39.629571],[-7.098037,39.030073],[-7.374092,38.373059],[-7.029281,38.075764],[-7.166508,37.803894],[-7.537105,37.428904],[-7.453726,37.097788],[-7.855613,36.838269],[-8.382816,36.97888],[-8.898857,36.868809],[-8.746101,37.651346],[-8.839998,38.266243],[-9.287464,38.358486],[-9.526571,38.737429],[-9.446989,39.392066],[-9.048305,39.755093],[-8.977353,40.159306],[-8.768684,40.760639],[-8.790853,41.184334],[-8.990789,41.543459],[-9.034818,41.880571]]]}}, -{"type":"Feature","id":"PRY","properties":{"name":"Paraguay"},"geometry":{"type":"Polygon","coordinates":[[[-62.685057,-22.249029],[-62.291179,-21.051635],[-62.265961,-20.513735],[-61.786326,-19.633737],[-60.043565,-19.342747],[-59.115042,-19.356906],[-58.183471,-19.868399],[-58.166392,-20.176701],[-57.870674,-20.732688],[-57.937156,-22.090176],[-56.88151,-22.282154],[-56.473317,-22.0863],[-55.797958,-22.35693],[-55.610683,-22.655619],[-55.517639,-23.571998],[-55.400747,-23.956935],[-55.027902,-24.001274],[-54.652834,-23.839578],[-54.29296,-24.021014],[-54.293476,-24.5708],[-54.428946,-25.162185],[-54.625291,-25.739255],[-54.788795,-26.621786],[-55.695846,-27.387837],[-56.486702,-27.548499],[-57.60976,-27.395899],[-58.618174,-27.123719],[-57.63366,-25.603657],[-57.777217,-25.16234],[-58.807128,-24.771459],[-60.028966,-24.032796],[-60.846565,-23.880713],[-62.685057,-22.249029]]]}}, -{"type":"Feature","id":"QAT","properties":{"name":"Qatar"},"geometry":{"type":"Polygon","coordinates":[[[50.810108,24.754743],[50.743911,25.482424],[51.013352,26.006992],[51.286462,26.114582],[51.589079,25.801113],[51.6067,25.21567],[51.389608,24.627386],[51.112415,24.556331],[50.810108,24.754743]]]}}, -{"type":"Feature","id":"ROU","properties":{"name":"Romania"},"geometry":{"type":"Polygon","coordinates":[[[22.710531,47.882194],[23.142236,48.096341],[23.760958,47.985598],[24.402056,47.981878],[24.866317,47.737526],[25.207743,47.891056],[25.945941,47.987149],[26.19745,48.220881],[26.619337,48.220726],[26.924176,48.123264],[27.233873,47.826771],[27.551166,47.405117],[28.12803,46.810476],[28.160018,46.371563],[28.054443,45.944586],[28.233554,45.488283],[28.679779,45.304031],[29.149725,45.464925],[29.603289,45.293308],[29.626543,45.035391],[29.141612,44.82021],[28.837858,44.913874],[28.558081,43.707462],[27.970107,43.812468],[27.2424,44.175986],[26.065159,43.943494],[25.569272,43.688445],[24.100679,43.741051],[23.332302,43.897011],[22.944832,43.823785],[22.65715,44.234923],[22.474008,44.409228],[22.705726,44.578003],[22.459022,44.702517],[22.145088,44.478422],[21.562023,44.768947],[21.483526,45.18117],[20.874313,45.416375],[20.762175,45.734573],[20.220192,46.127469],[21.021952,46.316088],[21.626515,46.994238],[22.099768,47.672439],[22.710531,47.882194]]]}}, -{"type":"Feature","id":"RUS","properties":{"name":"Russia"},"geometry":{"type":"MultiPolygon","coordinates":[[[[143.648007,50.7476],[144.654148,48.976391],[143.173928,49.306551],[142.558668,47.861575],[143.533492,46.836728],[143.505277,46.137908],[142.747701,46.740765],[142.09203,45.966755],[141.906925,46.805929],[142.018443,47.780133],[141.904445,48.859189],[142.1358,49.615163],[142.179983,50.952342],[141.594076,51.935435],[141.682546,53.301966],[142.606934,53.762145],[142.209749,54.225476],[142.654786,54.365881],[142.914616,53.704578],[143.260848,52.74076],[143.235268,51.75666],[143.648007,50.7476]]],[[[22.731099,54.327537],[20.892245,54.312525],[19.66064,54.426084],[19.888481,54.86616],[21.268449,55.190482],[22.315724,55.015299],[22.757764,54.856574],[22.651052,54.582741],[22.731099,54.327537]]],[[[-175.01425,66.58435],[-174.33983,66.33556],[-174.57182,67.06219],[-171.85731,66.91308],[-169.89958,65.97724],[-170.89107,65.54139],[-172.53025,65.43791],[-172.555,64.46079],[-172.95533,64.25269],[-173.89184,64.2826],[-174.65392,64.63125],[-175.98353,64.92288],[-176.20716,65.35667],[-177.22266,65.52024],[-178.35993,65.39052],[-178.90332,65.74044],[-178.68611,66.11211],[-179.88377,65.87456],[-179.43268,65.40411],[-180,64.979709],[-180,68.963636],[-177.55,68.2],[-174.92825,67.20589],[-175.01425,66.58435]]],[[[180,70.832199],[178.903425,70.78114],[178.7253,71.0988],[180,71.515714],[180,70.832199]]],[[[-178.69378,70.89302],[-180,70.832199],[-180,71.515714],[-179.871875,71.55762],[-179.02433,71.55553],[-177.577945,71.26948],[-177.663575,71.13277],[-178.69378,70.89302]]],[[[143.60385,73.21244],[142.08763,73.20544],[140.038155,73.31692],[139.86312,73.36983],[140.81171,73.76506],[142.06207,73.85758],[143.48283,73.47525],[143.60385,73.21244]]],[[[150.73167,75.08406],[149.575925,74.68892],[147.977465,74.778355],[146.11919,75.17298],[146.358485,75.49682],[148.22223,75.345845],[150.73167,75.08406]]],[[[145.086285,75.562625],[144.3,74.82],[140.61381,74.84768],[138.95544,74.61148],[136.97439,75.26167],[137.51176,75.94917],[138.831075,76.13676],[141.471615,76.09289],[145.086285,75.562625]]],[[[57.535693,70.720464],[56.944979,70.632743],[53.677375,70.762658],[53.412017,71.206662],[51.601895,71.474759],[51.455754,72.014881],[52.478275,72.229442],[52.444169,72.774731],[54.427614,73.627548],[53.50829,73.749814],[55.902459,74.627486],[55.631933,75.081412],[57.868644,75.60939],[61.170044,76.251883],[64.498368,76.439055],[66.210977,76.809782],[68.15706,76.939697],[68.852211,76.544811],[68.180573,76.233642],[64.637326,75.737755],[61.583508,75.260885],[58.477082,74.309056],[56.986786,73.333044],[55.419336,72.371268],[55.622838,71.540595],[57.535693,70.720464]]],[[[106.97013,76.97419],[107.24,76.48],[108.1538,76.72335],[111.07726,76.71],[113.33151,76.22224],[114.13417,75.84764],[113.88539,75.32779],[112.77918,75.03186],[110.15125,74.47673],[109.4,74.18],[110.64,74.04],[112.11919,73.78774],[113.01954,73.97693],[113.52958,73.33505],[113.96881,73.59488],[115.56782,73.75285],[118.77633,73.58772],[119.02,73.12],[123.20066,72.97122],[123.25777,73.73503],[125.38,73.56],[126.97644,73.56549],[128.59126,73.03871],[129.05157,72.39872],[128.46,71.98],[129.71599,71.19304],[131.28858,70.78699],[132.2535,71.8363],[133.85766,71.38642],[135.56193,71.65525],[137.49755,71.34763],[138.23409,71.62803],[139.86983,71.48783],[139.14791,72.41619],[140.46817,72.84941],[149.5,72.2],[150.35118,71.60643],[152.9689,70.84222],[157.00688,71.03141],[158.99779,70.86672],[159.83031,70.45324],[159.70866,69.72198],[160.94053,69.43728],[162.27907,69.64204],[164.05248,69.66823],[165.94037,69.47199],[167.83567,69.58269],[169.57763,68.6938],[170.81688,69.01363],[170.0082,69.65276],[170.45345,70.09703],[173.64391,69.81743],[175.72403,69.87725],[178.6,69.4],[180,68.963636],[180,64.979709],[179.99281,64.97433],[178.7072,64.53493],[177.41128,64.60821],[178.313,64.07593],[178.90825,63.25197],[179.37034,62.98262],[179.48636,62.56894],[179.22825,62.3041],[177.3643,62.5219],[174.56929,61.76915],[173.68013,61.65261],[172.15,60.95],[170.6985,60.33618],[170.33085,59.88177],[168.90046,60.57355],[166.29498,59.78855],[165.84,60.16],[164.87674,59.7316],[163.53929,59.86871],[163.21711,59.21101],[162.01733,58.24328],[162.05297,57.83912],[163.19191,57.61503],[163.05794,56.15924],[162.12958,56.12219],[161.70146,55.28568],[162.11749,54.85514],[160.36877,54.34433],[160.02173,53.20257],[158.53094,52.95868],[158.23118,51.94269],[156.78979,51.01105],[156.42,51.7],[155.99182,53.15895],[155.43366,55.38103],[155.91442,56.76792],[156.75815,57.3647],[156.81035,57.83204],[158.36433,58.05575],[160.15064,59.31477],[161.87204,60.343],[163.66969,61.1409],[164.47355,62.55061],[163.25842,62.46627],[162.65791,61.6425],[160.12148,60.54423],[159.30232,61.77396],[156.72068,61.43442],[154.21806,59.75818],[155.04375,59.14495],[152.81185,58.88385],[151.26573,58.78089],[151.33815,59.50396],[149.78371,59.65573],[148.54481,59.16448],[145.48722,59.33637],[142.19782,59.03998],[138.95848,57.08805],[135.12619,54.72959],[136.70171,54.60355],[137.19342,53.97732],[138.1647,53.75501],[138.80463,54.25455],[139.90151,54.18968],[141.34531,53.08957],[141.37923,52.23877],[140.59742,51.23967],[140.51308,50.04553],[140.06193,48.44671],[138.55472,46.99965],[138.21971,46.30795],[136.86232,45.1435],[135.51535,43.989],[134.86939,43.39821],[133.53687,42.81147],[132.90627,42.79849],[132.27807,43.28456],[130.93587,42.55274],[130.78,42.22],[130.64,42.395],[130.633866,42.903015],[131.144688,42.92999],[131.288555,44.11152],[131.02519,44.96796],[131.883454,45.321162],[133.09712,45.14409],[133.769644,46.116927],[134.11235,47.21248],[134.50081,47.57845],[135.026311,48.47823],[133.373596,48.183442],[132.50669,47.78896],[130.98726,47.79013],[130.582293,48.729687],[129.397818,49.4406],[127.6574,49.76027],[127.287456,50.739797],[126.939157,51.353894],[126.564399,51.784255],[125.946349,52.792799],[125.068211,53.161045],[123.57147,53.4588],[122.245748,53.431726],[121.003085,53.251401],[120.177089,52.753886],[120.725789,52.516226],[120.7382,51.96411],[120.18208,51.64355],[119.27939,50.58292],[119.288461,50.142883],[117.879244,49.510983],[116.678801,49.888531],[115.485695,49.805177],[114.96211,50.140247],[114.362456,50.248303],[112.89774,49.543565],[111.581231,49.377968],[110.662011,49.130128],[109.402449,49.292961],[108.475167,49.282548],[107.868176,49.793705],[106.888804,50.274296],[105.886591,50.406019],[104.62158,50.27532],[103.676545,50.089966],[102.25589,50.51056],[102.06521,51.25991],[100.88948,51.516856],[99.981732,51.634006],[98.861491,52.047366],[97.82574,51.010995],[98.231762,50.422401],[97.25976,49.72605],[95.81402,49.97746],[94.815949,50.013433],[94.147566,50.480537],[93.10421,50.49529],[92.234712,50.802171],[90.713667,50.331812],[88.805567,49.470521],[87.751264,49.297198],[87.35997,49.214981],[86.829357,49.826675],[85.54127,49.692859],[85.11556,50.117303],[84.416377,50.3114],[83.935115,50.889246],[83.383004,51.069183],[81.945986,50.812196],[80.568447,51.388336],[80.03556,50.864751],[77.800916,53.404415],[76.525179,54.177003],[76.8911,54.490524],[74.38482,53.54685],[73.425679,53.48981],[73.508516,54.035617],[72.22415,54.376655],[71.180131,54.133285],[70.865267,55.169734],[69.068167,55.38525],[68.1691,54.970392],[65.66687,54.60125],[65.178534,54.354228],[61.4366,54.00625],[60.978066,53.664993],[61.699986,52.979996],[60.739993,52.719986],[60.927269,52.447548],[59.967534,51.96042],[61.588003,51.272659],[61.337424,50.79907],[59.932807,50.842194],[59.642282,50.545442],[58.36332,51.06364],[56.77798,51.04355],[55.71694,50.62171],[54.532878,51.02624],[52.328724,51.718652],[50.766648,51.692762],[48.702382,50.605128],[48.577841,49.87476],[47.54948,50.454698],[46.751596,49.356006],[47.043672,49.152039],[46.466446,48.394152],[47.31524,47.71585],[48.05725,47.74377],[48.694734,47.075628],[48.59325,46.56104],[49.10116,46.39933],[48.64541,45.80629],[47.67591,45.64149],[46.68201,44.6092],[47.59094,43.66016],[47.49252,42.98658],[48.58437,41.80888],[47.987283,41.405819],[47.815666,41.151416],[47.373315,41.219732],[46.686071,41.827137],[46.404951,41.860675],[45.7764,42.09244],[45.470279,42.502781],[44.537623,42.711993],[43.93121,42.55496],[43.75599,42.74083],[42.3944,43.2203],[40.92219,43.38215],[40.076965,43.553104],[39.955009,43.434998],[38.68,44.28],[37.53912,44.65721],[36.67546,45.24469],[37.40317,45.40451],[38.23295,46.24087],[37.67372,46.63657],[39.14767,47.04475],[39.1212,47.26336],[38.223538,47.10219],[38.255112,47.5464],[38.77057,47.82562],[39.738278,47.898937],[39.89562,48.23241],[39.67465,48.78382],[40.080789,49.30743],[40.06904,49.60105],[38.594988,49.926462],[38.010631,49.915662],[37.39346,50.383953],[36.626168,50.225591],[35.356116,50.577197],[35.37791,50.77394],[35.022183,51.207572],[34.224816,51.255993],[34.141978,51.566413],[34.391731,51.768882],[33.7527,52.335075],[32.715761,52.238465],[32.412058,52.288695],[32.15944,52.06125],[31.78597,52.10168],[31.540018,52.742052],[31.305201,53.073996],[31.49764,53.16743],[32.304519,53.132726],[32.693643,53.351421],[32.405599,53.618045],[31.731273,53.794029],[31.791424,53.974639],[31.384472,54.157056],[30.757534,54.811771],[30.971836,55.081548],[30.873909,55.550976],[29.896294,55.789463],[29.371572,55.670091],[29.229513,55.918344],[28.176709,56.16913],[27.855282,56.759326],[27.770016,57.244258],[27.288185,57.474528],[27.716686,57.791899],[27.42015,58.72457],[28.131699,59.300825],[27.98112,59.47537],[29.1177,60.02805],[28.07,60.50352],[30.211107,61.780028],[31.139991,62.357693],[31.516092,62.867687],[30.035872,63.552814],[30.444685,64.204453],[29.54443,64.948672],[30.21765,65.80598],[29.054589,66.944286],[29.977426,67.698297],[28.445944,68.364613],[28.59193,69.064777],[29.39955,69.15692],[31.10108,69.55811],[32.13272,69.90595],[33.77547,69.30142],[36.51396,69.06342],[40.29234,67.9324],[41.05987,67.45713],[41.12595,66.79158],[40.01583,66.26618],[38.38295,65.99953],[33.91871,66.75961],[33.18444,66.63253],[34.81477,65.90015],[34.878574,65.436213],[34.94391,64.41437],[36.23129,64.10945],[37.01273,63.84983],[37.14197,64.33471],[36.539579,64.76446],[37.17604,65.14322],[39.59345,64.52079],[40.4356,64.76446],[39.7626,65.49682],[42.09309,66.47623],[43.01604,66.41858],[43.94975,66.06908],[44.53226,66.75634],[43.69839,67.35245],[44.18795,67.95051],[43.45282,68.57079],[46.25,68.25],[46.82134,67.68997],[45.55517,67.56652],[45.56202,67.01005],[46.34915,66.66767],[47.89416,66.88455],[48.13876,67.52238],[50.22766,67.99867],[53.71743,68.85738],[54.47171,68.80815],[53.48582,68.20131],[54.72628,68.09702],[55.44268,68.43866],[57.31702,68.46628],[58.802,68.88082],[59.94142,68.27844],[61.07784,68.94069],[60.03,69.52],[60.55,69.85],[63.504,69.54739],[64.888115,69.234835],[68.51216,68.09233],[69.18068,68.61563],[68.16444,69.14436],[68.13522,69.35649],[66.93008,69.45461],[67.25976,69.92873],[66.72492,70.70889],[66.69466,71.02897],[68.54006,71.9345],[69.19636,72.84336],[69.94,73.04],[72.58754,72.77629],[72.79603,72.22006],[71.84811,71.40898],[72.47011,71.09019],[72.79188,70.39114],[72.5647,69.02085],[73.66787,68.4079],[73.2387,67.7404],[71.28,66.32],[72.42301,66.17267],[72.82077,66.53267],[73.92099,66.78946],[74.18651,67.28429],[75.052,67.76047],[74.46926,68.32899],[74.93584,68.98918],[73.84236,69.07146],[73.60187,69.62763],[74.3998,70.63175],[73.1011,71.44717],[74.89082,72.12119],[74.65926,72.83227],[75.15801,72.85497],[75.68351,72.30056],[75.28898,71.33556],[76.35911,71.15287],[75.90313,71.87401],[77.57665,72.26717],[79.65202,72.32011],[81.5,71.75],[80.61071,72.58285],[80.51109,73.6482],[82.25,73.85],[84.65526,73.80591],[86.8223,73.93688],[86.00956,74.45967],[87.16682,75.11643],[88.31571,75.14393],[90.26,75.64],[92.90058,75.77333],[93.23421,76.0472],[95.86,76.14],[96.67821,75.91548],[98.92254,76.44689],[100.75967,76.43028],[101.03532,76.86189],[101.99084,77.28754],[104.3516,77.69792],[106.06664,77.37389],[104.705,77.1274],[106.97013,76.97419]]],[[[105.07547,78.30689],[99.43814,77.921],[101.2649,79.23399],[102.08635,79.34641],[102.837815,79.28129],[105.37243,78.71334],[105.07547,78.30689]]],[[[51.136187,80.54728],[49.793685,80.415428],[48.894411,80.339567],[48.754937,80.175468],[47.586119,80.010181],[46.502826,80.247247],[47.072455,80.559424],[44.846958,80.58981],[46.799139,80.771918],[48.318477,80.78401],[48.522806,80.514569],[49.09719,80.753986],[50.039768,80.918885],[51.522933,80.699726],[51.136187,80.54728]]],[[[99.93976,78.88094],[97.75794,78.7562],[94.97259,79.044745],[93.31288,79.4265],[92.5454,80.14379],[91.18107,80.34146],[93.77766,81.0246],[95.940895,81.2504],[97.88385,80.746975],[100.186655,79.780135],[99.93976,78.88094]]]]}}, -{"type":"Feature","id":"RWA","properties":{"name":"Rwanda"},"geometry":{"type":"Polygon","coordinates":[[[30.419105,-1.134659],[30.816135,-1.698914],[30.758309,-2.28725],[30.469696,-2.413858],[29.938359,-2.348487],[29.632176,-2.917858],[29.024926,-2.839258],[29.117479,-2.292211],[29.254835,-2.21511],[29.291887,-1.620056],[29.579466,-1.341313],[29.821519,-1.443322],[30.419105,-1.134659]]]}}, -{"type":"Feature","id":"ESH","properties":{"name":"Western Sahara"},"geometry":{"type":"Polygon","coordinates":[[[-8.794884,27.120696],[-8.817828,27.656426],[-8.66559,27.656426],[-8.665124,27.589479],[-8.6844,27.395744],[-8.687294,25.881056],[-11.969419,25.933353],[-11.937224,23.374594],[-12.874222,23.284832],[-13.118754,22.77122],[-12.929102,21.327071],[-16.845194,21.333323],[-17.063423,20.999752],[-17.020428,21.42231],[-17.002962,21.420734],[-14.750955,21.5006],[-14.630833,21.86094],[-14.221168,22.310163],[-13.89111,23.691009],[-12.500963,24.770116],[-12.030759,26.030866],[-11.71822,26.104092],[-11.392555,26.883424],[-10.551263,26.990808],[-10.189424,26.860945],[-9.735343,26.860945],[-9.413037,27.088476],[-8.794884,27.120696]]]}}, -{"type":"Feature","id":"SAU","properties":{"name":"Saudi Arabia"},"geometry":{"type":"Polygon","coordinates":[[[42.779332,16.347891],[42.649573,16.774635],[42.347989,17.075806],[42.270888,17.474722],[41.754382,17.833046],[41.221391,18.6716],[40.939341,19.486485],[40.247652,20.174635],[39.801685,20.338862],[39.139399,21.291905],[39.023696,21.986875],[39.066329,22.579656],[38.492772,23.688451],[38.02386,24.078686],[37.483635,24.285495],[37.154818,24.858483],[37.209491,25.084542],[36.931627,25.602959],[36.639604,25.826228],[36.249137,26.570136],[35.640182,27.37652],[35.130187,28.063352],[34.632336,28.058546],[34.787779,28.607427],[34.83222,28.957483],[34.956037,29.356555],[36.068941,29.197495],[36.501214,29.505254],[36.740528,29.865283],[37.503582,30.003776],[37.66812,30.338665],[37.998849,30.5085],[37.002166,31.508413],[39.004886,32.010217],[39.195468,32.161009],[40.399994,31.889992],[41.889981,31.190009],[44.709499,29.178891],[46.568713,29.099025],[47.459822,29.002519],[47.708851,28.526063],[48.416094,28.552004],[48.807595,27.689628],[49.299554,27.461218],[49.470914,27.109999],[50.152422,26.689663],[50.212935,26.277027],[50.113303,25.943972],[50.239859,25.60805],[50.527387,25.327808],[50.660557,24.999896],[50.810108,24.754743],[51.112415,24.556331],[51.389608,24.627386],[51.579519,24.245497],[51.617708,24.014219],[52.000733,23.001154],[55.006803,22.496948],[55.208341,22.70833],[55.666659,22.000001],[54.999982,19.999994],[52.00001,19.000003],[49.116672,18.616668],[48.183344,18.166669],[47.466695,17.116682],[47.000005,16.949999],[46.749994,17.283338],[46.366659,17.233315],[45.399999,17.333335],[45.216651,17.433329],[44.062613,17.410359],[43.791519,17.319977],[43.380794,17.579987],[43.115798,17.08844],[43.218375,16.66689],[42.779332,16.347891]]]}}, -{"type":"Feature","id":"SDN","properties":{"name":"Sudan"},"geometry":{"type":"Polygon","coordinates":[[[33.963393,9.464285],[33.824963,9.484061],[33.842131,9.981915],[33.721959,10.325262],[33.206938,10.720112],[33.086766,11.441141],[33.206938,12.179338],[32.743419,12.248008],[32.67475,12.024832],[32.073892,11.97333],[32.314235,11.681484],[32.400072,11.080626],[31.850716,10.531271],[31.352862,9.810241],[30.837841,9.707237],[29.996639,10.290927],[29.618957,10.084919],[29.515953,9.793074],[29.000932,9.604232],[28.966597,9.398224],[27.97089,9.398224],[27.833551,9.604232],[27.112521,9.638567],[26.752006,9.466893],[26.477328,9.55273],[25.962307,10.136421],[25.790633,10.411099],[25.069604,10.27376],[24.794926,9.810241],[24.537415,8.917538],[24.194068,8.728696],[23.88698,8.61973],[23.805813,8.666319],[23.459013,8.954286],[23.394779,9.265068],[23.55725,9.681218],[23.554304,10.089255],[22.977544,10.714463],[22.864165,11.142395],[22.87622,11.38461],[22.50869,11.67936],[22.49762,12.26024],[22.28801,12.64605],[21.93681,12.58818],[22.03759,12.95546],[22.29658,13.37232],[22.18329,13.78648],[22.51202,14.09318],[22.30351,14.32682],[22.56795,14.94429],[23.02459,15.68072],[23.88689,15.61084],[23.83766,19.58047],[23.85,20],[25,20.00304],[25,22],[29.02,22],[32.9,22],[36.86623,22],[37.18872,21.01885],[36.96941,20.83744],[37.1147,19.80796],[37.48179,18.61409],[37.86276,18.36786],[38.41009,17.998307],[37.904,17.42754],[37.16747,17.26314],[36.85253,16.95655],[36.75389,16.29186],[36.32322,14.82249],[36.42951,14.42211],[36.27022,13.56333],[35.86363,12.57828],[35.26049,12.08286],[34.83163,11.31896],[34.73115,10.91017],[34.25745,10.63009],[33.96162,9.58358],[33.963393,9.464285]]]}}, -{"type":"Feature","id":"SSD","properties":{"name":"South Sudan"},"geometry":{"type":"Polygon","coordinates":[[[33.963393,9.464285],[33.97498,8.68456],[33.8255,8.37916],[33.2948,8.35458],[32.95418,7.78497],[33.56829,7.71334],[34.0751,7.22595],[34.25032,6.82607],[34.70702,6.59422],[35.298007,5.506],[34.620196,4.847123],[34.005,4.249885],[33.39,3.79],[32.68642,3.79232],[31.88145,3.55827],[31.24556,3.7819],[30.83385,3.50917],[29.95349,4.1737],[29.715995,4.600805],[29.159078,4.389267],[28.696678,4.455077],[28.428994,4.287155],[27.979977,4.408413],[27.374226,5.233944],[27.213409,5.550953],[26.465909,5.946717],[26.213418,6.546603],[25.796648,6.979316],[25.124131,7.500085],[25.114932,7.825104],[24.567369,8.229188],[23.88698,8.61973],[24.194068,8.728696],[24.537415,8.917538],[24.794926,9.810241],[25.069604,10.27376],[25.790633,10.411099],[25.962307,10.136421],[26.477328,9.55273],[26.752006,9.466893],[27.112521,9.638567],[27.833551,9.604232],[27.97089,9.398224],[28.966597,9.398224],[29.000932,9.604232],[29.515953,9.793074],[29.618957,10.084919],[29.996639,10.290927],[30.837841,9.707237],[31.352862,9.810241],[31.850716,10.531271],[32.400072,11.080626],[32.314235,11.681484],[32.073892,11.97333],[32.67475,12.024832],[32.743419,12.248008],[33.206938,12.179338],[33.086766,11.441141],[33.206938,10.720112],[33.721959,10.325262],[33.842131,9.981915],[33.824963,9.484061],[33.963393,9.464285]]]}}, -{"type":"Feature","id":"SEN","properties":{"name":"Senegal"},"geometry":{"type":"Polygon","coordinates":[[[-16.713729,13.594959],[-17.126107,14.373516],[-17.625043,14.729541],[-17.185173,14.919477],[-16.700706,15.621527],[-16.463098,16.135036],[-16.12069,16.455663],[-15.623666,16.369337],[-15.135737,16.587282],[-14.577348,16.598264],[-14.099521,16.304302],[-13.435738,16.039383],[-12.830658,15.303692],[-12.17075,14.616834],[-12.124887,13.994727],[-11.927716,13.422075],[-11.553398,13.141214],[-11.467899,12.754519],[-11.513943,12.442988],[-11.658301,12.386583],[-12.203565,12.465648],[-12.278599,12.35444],[-12.499051,12.33209],[-13.217818,12.575874],[-13.700476,12.586183],[-15.548477,12.62817],[-15.816574,12.515567],[-16.147717,12.547762],[-16.677452,12.384852],[-16.841525,13.151394],[-15.931296,13.130284],[-15.691001,13.270353],[-15.511813,13.27857],[-15.141163,13.509512],[-14.712197,13.298207],[-14.277702,13.280585],[-13.844963,13.505042],[-14.046992,13.794068],[-14.376714,13.62568],[-14.687031,13.630357],[-15.081735,13.876492],[-15.39877,13.860369],[-15.624596,13.623587],[-16.713729,13.594959]]]}}, -{"type":"Feature","id":"SLB","properties":{"name":"Solomon Islands"},"geometry":{"type":"MultiPolygon","coordinates":[[[[162.119025,-10.482719],[162.398646,-10.826367],[161.700032,-10.820011],[161.319797,-10.204751],[161.917383,-10.446701],[162.119025,-10.482719]]],[[[160.852229,-9.872937],[160.462588,-9.89521],[159.849447,-9.794027],[159.640003,-9.63998],[159.702945,-9.24295],[160.362956,-9.400304],[160.688518,-9.610162],[160.852229,-9.872937]]],[[[161.679982,-9.599982],[161.529397,-9.784312],[160.788253,-8.917543],[160.579997,-8.320009],[160.920028,-8.320009],[161.280006,-9.120011],[161.679982,-9.599982]]],[[[159.875027,-8.33732],[159.917402,-8.53829],[159.133677,-8.114181],[158.586114,-7.754824],[158.21115,-7.421872],[158.359978,-7.320018],[158.820001,-7.560003],[159.640003,-8.020027],[159.875027,-8.33732]]],[[[157.538426,-7.34782],[157.33942,-7.404767],[156.90203,-7.176874],[156.491358,-6.765943],[156.542828,-6.599338],[157.14,-7.021638],[157.538426,-7.34782]]]]}}, -{"type":"Feature","id":"SLE","properties":{"name":"Sierra Leone"},"geometry":{"type":"Polygon","coordinates":[[[-11.438779,6.785917],[-11.708195,6.860098],[-12.428099,7.262942],[-12.949049,7.798646],[-13.124025,8.163946],[-13.24655,8.903049],[-12.711958,9.342712],[-12.596719,9.620188],[-12.425929,9.835834],[-12.150338,9.858572],[-11.917277,10.046984],[-11.117481,10.045873],[-10.839152,9.688246],[-10.622395,9.26791],[-10.65477,8.977178],[-10.494315,8.715541],[-10.505477,8.348896],[-10.230094,8.406206],[-10.695595,7.939464],[-11.146704,7.396706],[-11.199802,7.105846],[-11.438779,6.785917]]]}}, -{"type":"Feature","id":"SLV","properties":{"name":"El Salvador"},"geometry":{"type":"Polygon","coordinates":[[[-87.793111,13.38448],[-87.904112,13.149017],[-88.483302,13.163951],[-88.843228,13.259734],[-89.256743,13.458533],[-89.812394,13.520622],[-90.095555,13.735338],[-90.064678,13.88197],[-89.721934,14.134228],[-89.534219,14.244816],[-89.587343,14.362586],[-89.353326,14.424133],[-89.058512,14.340029],[-88.843073,14.140507],[-88.541231,13.980155],[-88.503998,13.845486],[-88.065343,13.964626],[-87.859515,13.893312],[-87.723503,13.78505],[-87.793111,13.38448]]]}}, -{"type":"Feature","id":"-99","properties":{"name":"Somaliland"},"geometry":{"type":"Polygon","coordinates":[[[48.93813,9.451749],[48.486736,8.837626],[47.78942,8.003],[46.948328,7.996877],[43.67875,9.18358],[43.296975,9.540477],[42.92812,10.02194],[42.55876,10.57258],[42.776852,10.926879],[43.145305,11.46204],[43.47066,11.27771],[43.666668,10.864169],[44.117804,10.445538],[44.614259,10.442205],[45.556941,10.698029],[46.645401,10.816549],[47.525658,11.127228],[48.021596,11.193064],[48.378784,11.375482],[48.948206,11.410622],[48.942005,11.394266],[48.938491,10.982327],[48.938233,9.9735],[48.93813,9.451749]]]}}, -{"type":"Feature","id":"SOM","properties":{"name":"Somalia"},"geometry":{"type":"Polygon","coordinates":[[[49.72862,11.5789],[50.25878,11.67957],[50.73202,12.0219],[51.1112,12.02464],[51.13387,11.74815],[51.04153,11.16651],[51.04531,10.6409],[50.83418,10.27972],[50.55239,9.19874],[50.07092,8.08173],[49.4527,6.80466],[48.59455,5.33911],[47.74079,4.2194],[46.56476,2.85529],[45.56399,2.04576],[44.06815,1.05283],[43.13597,0.2922],[42.04157,-0.91916],[41.81095,-1.44647],[41.58513,-1.68325],[40.993,-0.85829],[40.98105,2.78452],[41.855083,3.918912],[42.12861,4.23413],[42.76967,4.25259],[43.66087,4.95755],[44.9636,5.00162],[47.78942,8.003],[48.486736,8.837626],[48.93813,9.451749],[48.938233,9.9735],[48.938491,10.982327],[48.942005,11.394266],[48.948205,11.410617],[49.26776,11.43033],[49.72862,11.5789]]]}}, -{"type":"Feature","id":"SRB","properties":{"name":"Republic of Serbia"},"geometry":{"type":"Polygon","coordinates":[[[20.874313,45.416375],[21.483526,45.18117],[21.562023,44.768947],[22.145088,44.478422],[22.459022,44.702517],[22.705726,44.578003],[22.474008,44.409228],[22.65715,44.234923],[22.410446,44.008063],[22.500157,43.642814],[22.986019,43.211161],[22.604801,42.898519],[22.436595,42.580321],[22.545012,42.461362],[22.380526,42.32026],[21.91708,42.30364],[21.576636,42.245224],[21.54332,42.32025],[21.66292,42.43922],[21.77505,42.6827],[21.63302,42.67717],[21.43866,42.86255],[21.27421,42.90959],[21.143395,43.068685],[20.95651,43.13094],[20.81448,43.27205],[20.63508,43.21671],[20.49679,42.88469],[20.25758,42.81275],[20.3398,42.89852],[19.95857,43.10604],[19.63,43.21378],[19.48389,43.35229],[19.21852,43.52384],[19.454,43.5681],[19.59976,44.03847],[19.11761,44.42307],[19.36803,44.863],[19.00548,44.86023],[19.390476,45.236516],[19.072769,45.521511],[18.82982,45.90888],[19.596045,46.17173],[20.220192,46.127469],[20.762175,45.734573],[20.874313,45.416375]]]}}, -{"type":"Feature","id":"SUR","properties":{"name":"Suriname"},"geometry":{"type":"Polygon","coordinates":[[[-57.147436,5.97315],[-55.949318,5.772878],[-55.84178,5.953125],[-55.03325,6.025291],[-53.958045,5.756548],[-54.478633,4.896756],[-54.399542,4.212611],[-54.006931,3.620038],[-54.181726,3.18978],[-54.269705,2.732392],[-54.524754,2.311849],[-55.097587,2.523748],[-55.569755,2.421506],[-55.973322,2.510364],[-56.073342,2.220795],[-55.9056,2.021996],[-55.995698,1.817667],[-56.539386,1.899523],[-57.150098,2.768927],[-57.281433,3.333492],[-57.601569,3.334655],[-58.044694,4.060864],[-57.86021,4.576801],[-57.914289,4.812626],[-57.307246,5.073567],[-57.147436,5.97315]]]}}, -{"type":"Feature","id":"SVK","properties":{"name":"Slovakia"},"geometry":{"type":"Polygon","coordinates":[[[18.853144,49.49623],[18.909575,49.435846],[19.320713,49.571574],[19.825023,49.217125],[20.415839,49.431453],[20.887955,49.328772],[21.607808,49.470107],[22.558138,49.085738],[22.280842,48.825392],[22.085608,48.422264],[21.872236,48.319971],[20.801294,48.623854],[20.473562,48.56285],[20.239054,48.327567],[19.769471,48.202691],[19.661364,48.266615],[19.174365,48.111379],[18.777025,48.081768],[18.696513,47.880954],[17.857133,47.758429],[17.488473,47.867466],[16.979667,48.123497],[16.879983,48.470013],[16.960288,48.596982],[17.101985,48.816969],[17.545007,48.800019],[17.886485,48.903475],[17.913512,48.996493],[18.104973,49.043983],[18.170498,49.271515],[18.399994,49.315001],[18.554971,49.495015],[18.853144,49.49623]]]}}, -{"type":"Feature","id":"SVN","properties":{"name":"Slovenia"},"geometry":{"type":"Polygon","coordinates":[[[13.806475,46.509306],[14.632472,46.431817],[15.137092,46.658703],[16.011664,46.683611],[16.202298,46.852386],[16.370505,46.841327],[16.564808,46.503751],[15.768733,46.238108],[15.67153,45.834154],[15.323954,45.731783],[15.327675,45.452316],[14.935244,45.471695],[14.595109,45.634941],[14.411968,45.466166],[13.71506,45.500324],[13.93763,45.591016],[13.69811,46.016778],[13.806475,46.509306]]]}}, -{"type":"Feature","id":"SWE","properties":{"name":"Sweden"},"geometry":{"type":"MultiPolygon","coordinates":[[[[22.183173,65.723741],[21.213517,65.026005],[21.369631,64.413588],[19.778876,63.609554],[17.847779,62.7494],[17.119555,61.341166],[17.831346,60.636583],[18.787722,60.081914],[17.869225,58.953766],[16.829185,58.719827],[16.44771,57.041118],[15.879786,56.104302],[14.666681,56.200885],[14.100721,55.407781],[12.942911,55.361737],[12.625101,56.30708],[11.787942,57.441817],[11.027369,58.856149],[11.468272,59.432393],[12.300366,60.117933],[12.631147,61.293572],[11.992064,61.800362],[11.930569,63.128318],[12.579935,64.066219],[13.571916,64.049114],[13.919905,64.445421],[13.55569,64.787028],[15.108411,66.193867],[16.108712,67.302456],[16.768879,68.013937],[17.729182,68.010552],[17.993868,68.567391],[19.87856,68.407194],[20.025269,69.065139],[20.645593,69.106247],[21.978535,68.616846],[23.539473,67.936009],[23.56588,66.396051],[23.903379,66.006927],[22.183173,65.723741]],[[17.061767,57.385783],[17.210083,57.326521],[16.430053,56.179196],[16.364135,56.556455],[17.061767,57.385783]],[[19.357910,57.958588],[18.803100,57.651279],[18.825073,57.444949],[18.995361,57.441993],[18.951416,57.370976],[18.693237,57.305756],[18.709716,57.204734],[18.462524,57.127295],[18.319702,56.926992],[18.105468,56.891003],[18.187866,57.109402],[18.072509,57.267163],[18.154907,57.394664],[18.094482,57.545312],[18.660278,57.929434],[19.039306,57.941098],[19.105224,57.993543],[19.374389,57.996454],[19.357910,57.958588]],[[20.846557,63.823710],[21.066284,63.829768],[20.972900,63.715670],[20.824584,63.579121],[20.695495,63.591340],[20.819091,63.714454],[20.799865,63.780059],[20.846557,63.823710]]]]}}, -{"type":"Feature","id":"SWZ","properties":{"name":"Swaziland"},"geometry":{"type":"Polygon","coordinates":[[[32.071665,-26.73382],[31.86806,-27.177927],[31.282773,-27.285879],[30.685962,-26.743845],[30.676609,-26.398078],[30.949667,-26.022649],[31.04408,-25.731452],[31.333158,-25.660191],[31.837778,-25.843332],[31.985779,-26.29178],[32.071665,-26.73382]]]}}, -{"type":"Feature","id":"SYR","properties":{"name":"Syria"},"geometry":{"type":"Polygon","coordinates":[[[38.792341,33.378686],[36.834062,32.312938],[35.719918,32.709192],[35.700798,32.716014],[35.836397,32.868123],[35.821101,33.277426],[36.06646,33.824912],[36.61175,34.201789],[36.448194,34.593935],[35.998403,34.644914],[35.905023,35.410009],[36.149763,35.821535],[36.41755,36.040617],[36.685389,36.259699],[36.739494,36.81752],[37.066761,36.623036],[38.167727,36.90121],[38.699891,36.712927],[39.52258,36.716054],[40.673259,37.091276],[41.212089,37.074352],[42.349591,37.229873],[41.837064,36.605854],[41.289707,36.358815],[41.383965,35.628317],[41.006159,34.419372],[38.792341,33.378686]]]}}, -{"type":"Feature","id":"TCD","properties":{"name":"Chad"},"geometry":{"type":"Polygon","coordinates":[[[14.495787,12.859396],[14.595781,13.330427],[13.954477,13.353449],[13.956699,13.996691],[13.540394,14.367134],[13.97217,15.68437],[15.247731,16.627306],[15.300441,17.92795],[15.685741,19.95718],[15.903247,20.387619],[15.487148,20.730415],[15.47106,21.04845],[15.096888,21.308519],[14.8513,22.86295],[15.86085,23.40972],[19.84926,21.49509],[23.83766,19.58047],[23.88689,15.61084],[23.02459,15.68072],[22.56795,14.94429],[22.30351,14.32682],[22.51202,14.09318],[22.18329,13.78648],[22.29658,13.37232],[22.03759,12.95546],[21.93681,12.58818],[22.28801,12.64605],[22.49762,12.26024],[22.50869,11.67936],[22.87622,11.38461],[22.864165,11.142395],[22.231129,10.971889],[21.723822,10.567056],[21.000868,9.475985],[20.059685,9.012706],[19.094008,9.074847],[18.81201,8.982915],[18.911022,8.630895],[18.389555,8.281304],[17.96493,7.890914],[16.705988,7.508328],[16.456185,7.734774],[16.290562,7.754307],[16.106232,7.497088],[15.27946,7.421925],[15.436092,7.692812],[15.120866,8.38215],[14.979996,8.796104],[14.544467,8.965861],[13.954218,9.549495],[14.171466,10.021378],[14.627201,9.920919],[14.909354,9.992129],[15.467873,9.982337],[14.923565,10.891325],[14.960152,11.555574],[14.89336,12.21905],[14.495787,12.859396]]]}}, -{"type":"Feature","id":"TGO","properties":{"name":"Togo"},"geometry":{"type":"Polygon","coordinates":[[[1.865241,6.142158],[1.060122,5.928837],[0.836931,6.279979],[0.570384,6.914359],[0.490957,7.411744],[0.712029,8.312465],[0.461192,8.677223],[0.365901,9.465004],[0.36758,10.191213],[-0.049785,10.706918],[0.023803,11.018682],[0.899563,10.997339],[0.772336,10.470808],[1.077795,10.175607],[1.425061,9.825395],[1.463043,9.334624],[1.664478,9.12859],[1.618951,6.832038],[1.865241,6.142158]]]}}, -{"type":"Feature","id":"THA","properties":{"name":"Thailand"},"geometry":{"type":"Polygon","coordinates":[[[102.584932,12.186595],[101.687158,12.64574],[100.83181,12.627085],[100.978467,13.412722],[100.097797,13.406856],[100.018733,12.307001],[99.478921,10.846367],[99.153772,9.963061],[99.222399,9.239255],[99.873832,9.207862],[100.279647,8.295153],[100.459274,7.429573],[101.017328,6.856869],[101.623079,6.740622],[102.141187,6.221636],[101.814282,5.810808],[101.154219,5.691384],[101.075516,6.204867],[100.259596,6.642825],[100.085757,6.464489],[99.690691,6.848213],[99.519642,7.343454],[98.988253,7.907993],[98.503786,8.382305],[98.339662,7.794512],[98.150009,8.350007],[98.25915,8.973923],[98.553551,9.93296],[99.038121,10.960546],[99.587286,11.892763],[99.196354,12.804748],[99.212012,13.269294],[99.097755,13.827503],[98.430819,14.622028],[98.192074,15.123703],[98.537376,15.308497],[98.903348,16.177824],[98.493761,16.837836],[97.859123,17.567946],[97.375896,18.445438],[97.797783,18.62708],[98.253724,19.708203],[98.959676,19.752981],[99.543309,20.186598],[100.115988,20.41785],[100.548881,20.109238],[100.606294,19.508344],[101.282015,19.462585],[101.035931,18.408928],[101.059548,17.512497],[102.113592,18.109102],[102.413005,17.932782],[102.998706,17.961695],[103.200192,18.309632],[103.956477,18.240954],[104.716947,17.428859],[104.779321,16.441865],[105.589039,15.570316],[105.544338,14.723934],[105.218777,14.273212],[104.281418,14.416743],[102.988422,14.225721],[102.348099,13.394247],[102.584932,12.186595]]]}}, -{"type":"Feature","id":"TJK","properties":{"name":"Tajikistan"},"geometry":{"type":"Polygon","coordinates":[[[71.014198,40.244366],[70.648019,39.935754],[69.55961,40.103211],[69.464887,39.526683],[70.549162,39.604198],[71.784694,39.279463],[73.675379,39.431237],[73.928852,38.505815],[74.257514,38.606507],[74.864816,38.378846],[74.829986,37.990007],[74.980002,37.41999],[73.948696,37.421566],[73.260056,37.495257],[72.63689,37.047558],[72.193041,36.948288],[71.844638,36.738171],[71.448693,37.065645],[71.541918,37.905774],[71.239404,37.953265],[71.348131,38.258905],[70.806821,38.486282],[70.376304,38.138396],[70.270574,37.735165],[70.116578,37.588223],[69.518785,37.608997],[69.196273,37.151144],[68.859446,37.344336],[68.135562,37.023115],[67.83,37.144994],[68.392033,38.157025],[68.176025,38.901553],[67.44222,39.140144],[67.701429,39.580478],[68.536416,39.533453],[69.011633,40.086158],[69.329495,40.727824],[70.666622,40.960213],[70.45816,40.496495],[70.601407,40.218527],[71.014198,40.244366]]]}}, -{"type":"Feature","id":"TKM","properties":{"name":"Turkmenistan"},"geometry":{"type":"Polygon","coordinates":[[[61.210817,35.650072],[61.123071,36.491597],[60.377638,36.527383],[59.234762,37.412988],[58.436154,37.522309],[57.330434,38.029229],[56.619366,38.121394],[56.180375,37.935127],[55.511578,37.964117],[54.800304,37.392421],[53.921598,37.198918],[53.735511,37.906136],[53.880929,38.952093],[53.101028,39.290574],[53.357808,39.975286],[52.693973,40.033629],[52.915251,40.876523],[53.858139,40.631034],[54.736845,40.951015],[54.008311,41.551211],[53.721713,42.123191],[52.91675,41.868117],[52.814689,41.135371],[52.50246,41.783316],[52.944293,42.116034],[54.079418,42.324109],[54.755345,42.043971],[55.455251,41.259859],[55.968191,41.308642],[57.096391,41.32231],[56.932215,41.826026],[57.78653,42.170553],[58.629011,42.751551],[59.976422,42.223082],[60.083341,41.425146],[60.465953,41.220327],[61.547179,41.26637],[61.882714,41.084857],[62.37426,40.053886],[63.518015,39.363257],[64.170223,38.892407],[65.215999,38.402695],[66.54615,37.974685],[66.518607,37.362784],[66.217385,37.39379],[65.745631,37.661164],[65.588948,37.305217],[64.746105,37.111818],[64.546479,36.312073],[63.982896,36.007957],[63.193538,35.857166],[62.984662,35.404041],[62.230651,35.270664],[61.210817,35.650072]]]}}, -{"type":"Feature","id":"TLS","properties":{"name":"East Timor"},"geometry":{"type":"Polygon","coordinates":[[[124.968682,-8.89279],[125.086246,-8.656887],[125.947072,-8.432095],[126.644704,-8.398247],[126.957243,-8.273345],[127.335928,-8.397317],[126.967992,-8.668256],[125.925885,-9.106007],[125.08852,-9.393173],[125.07002,-9.089987],[124.968682,-8.89279]]]}}, -{"type":"Feature","id":"TTO","properties":{"name":"Trinidad and Tobago"},"geometry":{"type":"Polygon","coordinates":[[[-61.68,10.76],[-61.105,10.89],[-60.895,10.855],[-60.935,10.11],[-61.77,10],[-61.95,10.09],[-61.66,10.365],[-61.68,10.76]]]}}, -{"type":"Feature","id":"TUN","properties":{"name":"Tunisia"},"geometry":{"type":"Polygon","coordinates":[[[9.48214,30.307556],[9.055603,32.102692],[8.439103,32.506285],[8.430473,32.748337],[7.612642,33.344115],[7.524482,34.097376],[8.140981,34.655146],[8.376368,35.479876],[8.217824,36.433177],[8.420964,36.946427],[9.509994,37.349994],[10.210002,37.230002],[10.18065,36.724038],[11.028867,37.092103],[11.100026,36.899996],[10.600005,36.41],[10.593287,35.947444],[10.939519,35.698984],[10.807847,34.833507],[10.149593,34.330773],[10.339659,33.785742],[10.856836,33.76874],[11.108501,33.293343],[11.488787,33.136996],[11.432253,32.368903],[10.94479,32.081815],[10.636901,31.761421],[9.950225,31.37607],[10.056575,30.961831],[9.970017,30.539325],[9.48214,30.307556]]]}}, -{"type":"Feature","id":"TUR","properties":{"name":"Turkey"},"geometry":{"type":"MultiPolygon","coordinates":[[[[36.913127,41.335358],[38.347665,40.948586],[39.512607,41.102763],[40.373433,41.013673],[41.554084,41.535656],[42.619549,41.583173],[43.582746,41.092143],[43.752658,40.740201],[43.656436,40.253564],[44.400009,40.005],[44.79399,39.713003],[44.109225,39.428136],[44.421403,38.281281],[44.225756,37.971584],[44.772699,37.170445],[44.293452,37.001514],[43.942259,37.256228],[42.779126,37.385264],[42.349591,37.229873],[41.212089,37.074352],[40.673259,37.091276],[39.52258,36.716054],[38.699891,36.712927],[38.167727,36.90121],[37.066761,36.623036],[36.739494,36.81752],[36.685389,36.259699],[36.41755,36.040617],[36.149763,35.821535],[35.782085,36.274995],[36.160822,36.650606],[35.550936,36.565443],[34.714553,36.795532],[34.026895,36.21996],[32.509158,36.107564],[31.699595,36.644275],[30.621625,36.677865],[30.391096,36.262981],[29.699976,36.144357],[28.732903,36.676831],[27.641187,36.658822],[27.048768,37.653361],[26.318218,38.208133],[26.8047,38.98576],[26.170785,39.463612],[27.28002,40.420014],[28.819978,40.460011],[29.240004,41.219991],[31.145934,41.087622],[32.347979,41.736264],[33.513283,42.01896],[35.167704,42.040225],[36.913127,41.335358]]],[[[27.192377,40.690566],[26.358009,40.151994],[26.043351,40.617754],[26.056942,40.824123],[26.294602,40.936261],[26.604196,41.562115],[26.117042,41.826905],[27.135739,42.141485],[27.99672,42.007359],[28.115525,41.622886],[28.988443,41.299934],[28.806438,41.054962],[27.619017,40.999823],[27.192377,40.690566]]]]}}, -{"type":"Feature","id":"TWN","properties":{"name":"Taiwan"},"geometry":{"type":"Polygon","coordinates":[[[121.777818,24.394274],[121.175632,22.790857],[120.74708,21.970571],[120.220083,22.814861],[120.106189,23.556263],[120.69468,24.538451],[121.495044,25.295459],[121.951244,24.997596],[121.777818,24.394274]]]}}, -{"type":"Feature","id":"TZA","properties":{"name":"United Republic of Tanzania"},"geometry":{"type":"Polygon","coordinates":[[[33.903711,-0.95],[34.07262,-1.05982],[37.69869,-3.09699],[37.7669,-3.67712],[39.20222,-4.67677],[38.74054,-5.90895],[38.79977,-6.47566],[39.44,-6.84],[39.47,-7.1],[39.19469,-7.7039],[39.25203,-8.00781],[39.18652,-8.48551],[39.53574,-9.11237],[39.9496,-10.0984],[40.31659,-10.3171],[39.521,-10.89688],[38.427557,-11.285202],[37.82764,-11.26879],[37.47129,-11.56876],[36.775151,-11.594537],[36.514082,-11.720938],[35.312398,-11.439146],[34.559989,-11.52002],[34.28,-10.16],[33.940838,-9.693674],[33.73972,-9.41715],[32.759375,-9.230599],[32.191865,-8.930359],[31.556348,-8.762049],[31.157751,-8.594579],[30.74,-8.34],[30.2,-7.08],[29.62,-6.52],[29.419993,-5.939999],[29.519987,-5.419979],[29.339998,-4.499983],[29.753512,-4.452389],[30.11632,-4.09012],[30.50554,-3.56858],[30.75224,-3.35931],[30.74301,-3.03431],[30.52766,-2.80762],[30.46967,-2.41383],[30.758309,-2.28725],[30.816135,-1.698914],[30.419105,-1.134659],[30.76986,-1.01455],[31.86617,-1.02736],[33.903711,-0.95]]]}}, -{"type":"Feature","id":"UGA","properties":{"name":"Uganda"},"geometry":{"type":"Polygon","coordinates":[[[31.86617,-1.02736],[30.76986,-1.01455],[30.419105,-1.134659],[29.821519,-1.443322],[29.579466,-1.341313],[29.587838,-0.587406],[29.8195,-0.2053],[29.875779,0.59738],[30.086154,1.062313],[30.468508,1.583805],[30.85267,1.849396],[31.174149,2.204465],[30.77332,2.33989],[30.83385,3.50917],[31.24556,3.7819],[31.88145,3.55827],[32.68642,3.79232],[33.39,3.79],[34.005,4.249885],[34.47913,3.5556],[34.59607,3.05374],[35.03599,1.90584],[34.6721,1.17694],[34.18,0.515],[33.893569,0.109814],[33.903711,-0.95],[31.86617,-1.02736]]]}}, -{"type":"Feature","id":"UKR","properties":{"name":"Ukraine"},"geometry":{"type":"Polygon","coordinates":[[[31.785998,52.101678],[32.159412,52.061267],[32.412058,52.288695],[32.715761,52.238465],[33.7527,52.335075],[34.391731,51.768882],[34.141978,51.566413],[34.224816,51.255993],[35.022183,51.207572],[35.377924,50.773955],[35.356116,50.577197],[36.626168,50.225591],[37.39346,50.383953],[38.010631,49.915662],[38.594988,49.926462],[40.069058,49.601055],[40.080789,49.30743],[39.674664,48.783818],[39.895632,48.232405],[39.738278,47.898937],[38.770585,47.825608],[38.255112,47.5464],[38.223538,47.10219],[37.425137,47.022221],[36.759855,46.6987],[35.823685,46.645964],[34.962342,46.273197],[35.020788,45.651219],[35.510009,45.409993],[36.529998,45.46999],[36.334713,45.113216],[35.239999,44.939996],[33.882511,44.361479],[33.326421,44.564877],[33.546924,45.034771],[32.454174,45.327466],[32.630804,45.519186],[33.588162,45.851569],[33.298567,46.080598],[31.74414,46.333348],[31.675307,46.706245],[30.748749,46.5831],[30.377609,46.03241],[29.603289,45.293308],[29.149725,45.464925],[28.679779,45.304031],[28.233554,45.488283],[28.485269,45.596907],[28.659987,45.939987],[28.933717,46.25883],[28.862972,46.437889],[29.072107,46.517678],[29.170654,46.379262],[29.759972,46.349988],[30.024659,46.423937],[29.83821,46.525326],[29.908852,46.674361],[29.559674,46.928583],[29.415135,47.346645],[29.050868,47.510227],[29.122698,47.849095],[28.670891,48.118149],[28.259547,48.155562],[27.522537,48.467119],[26.857824,48.368211],[26.619337,48.220726],[26.19745,48.220881],[25.945941,47.987149],[25.207743,47.891056],[24.866317,47.737526],[24.402056,47.981878],[23.760958,47.985598],[23.142236,48.096341],[22.710531,47.882194],[22.64082,48.15024],[22.085608,48.422264],[22.280842,48.825392],[22.558138,49.085738],[22.776419,49.027395],[22.51845,49.476774],[23.426508,50.308506],[23.922757,50.424881],[24.029986,50.705407],[23.527071,51.578454],[24.005078,51.617444],[24.553106,51.888461],[25.327788,51.910656],[26.337959,51.832289],[27.454066,51.592303],[28.241615,51.572227],[28.617613,51.427714],[28.992835,51.602044],[29.254938,51.368234],[30.157364,51.416138],[30.555117,51.319503],[30.619454,51.822806],[30.927549,52.042353],[31.785998,52.101678]]]}}, -{"type":"Feature","id":"URY","properties":{"name":"Uruguay"},"geometry":{"type":"Polygon","coordinates":[[[-57.625133,-30.216295],[-56.976026,-30.109686],[-55.973245,-30.883076],[-55.60151,-30.853879],[-54.572452,-31.494511],[-53.787952,-32.047243],[-53.209589,-32.727666],[-53.650544,-33.202004],[-53.373662,-33.768378],[-53.806426,-34.396815],[-54.935866,-34.952647],[-55.67409,-34.752659],[-56.215297,-34.859836],[-57.139685,-34.430456],[-57.817861,-34.462547],[-58.427074,-33.909454],[-58.349611,-33.263189],[-58.132648,-33.040567],[-58.14244,-32.044504],[-57.874937,-31.016556],[-57.625133,-30.216295]]]}}, -{"type":"Feature","id":"USA","properties":{"name":"United States of America"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-155.54211,19.08348],[-155.68817,18.91619],[-155.93665,19.05939],[-155.90806,19.33888],[-156.07347,19.70294],[-156.02368,19.81422],[-155.85008,19.97729],[-155.91907,20.17395],[-155.86108,20.26721],[-155.78505,20.2487],[-155.40214,20.07975],[-155.22452,19.99302],[-155.06226,19.8591],[-154.80741,19.50871],[-154.83147,19.45328],[-155.22217,19.23972],[-155.54211,19.08348]]],[[[-156.07926,20.64397],[-156.41445,20.57241],[-156.58673,20.783],[-156.70167,20.8643],[-156.71055,20.92676],[-156.61258,21.01249],[-156.25711,20.91745],[-155.99566,20.76404],[-156.07926,20.64397]]],[[[-156.75824,21.17684],[-156.78933,21.06873],[-157.32521,21.09777],[-157.25027,21.21958],[-156.75824,21.17684]]],[[[-157.65283,21.32217],[-157.70703,21.26442],[-157.7786,21.27729],[-158.12667,21.31244],[-158.2538,21.53919],[-158.29265,21.57912],[-158.0252,21.71696],[-157.94161,21.65272],[-157.65283,21.32217]]],[[[-159.34512,21.982],[-159.46372,21.88299],[-159.80051,22.06533],[-159.74877,22.1382],[-159.5962,22.23618],[-159.36569,22.21494],[-159.34512,21.982]]],[[[-94.81758,49.38905],[-94.64,48.84],[-94.32914,48.67074],[-93.63087,48.60926],[-92.61,48.45],[-91.64,48.14],[-90.83,48.27],[-89.6,48.01],[-89.272917,48.019808],[-88.378114,48.302918],[-87.439793,47.94],[-86.461991,47.553338],[-85.652363,47.220219],[-84.87608,46.900083],[-84.779238,46.637102],[-84.543749,46.538684],[-84.6049,46.4396],[-84.3367,46.40877],[-84.14212,46.512226],[-84.091851,46.275419],[-83.890765,46.116927],[-83.616131,46.116927],[-83.469551,45.994686],[-83.592851,45.816894],[-82.550925,45.347517],[-82.337763,44.44],[-82.137642,43.571088],[-82.43,42.98],[-82.9,42.43],[-83.12,42.08],[-83.142,41.975681],[-83.02981,41.832796],[-82.690089,41.675105],[-82.439278,41.675105],[-81.277747,42.209026],[-80.247448,42.3662],[-78.939362,42.863611],[-78.92,42.965],[-79.01,43.27],[-79.171674,43.466339],[-78.72028,43.625089],[-77.737885,43.629056],[-76.820034,43.628784],[-76.5,44.018459],[-76.375,44.09631],[-75.31821,44.81645],[-74.867,45.00048],[-73.34783,45.00738],[-71.50506,45.0082],[-71.405,45.255],[-71.08482,45.30524],[-70.66,45.46],[-70.305,45.915],[-69.99997,46.69307],[-69.237216,47.447781],[-68.905,47.185],[-68.23444,47.35486],[-67.79046,47.06636],[-67.79134,45.70281],[-67.13741,45.13753],[-66.96466,44.8097],[-68.03252,44.3252],[-69.06,43.98],[-70.11617,43.68405],[-70.645476,43.090238],[-70.81489,42.8653],[-70.825,42.335],[-70.495,41.805],[-70.08,41.78],[-70.185,42.145],[-69.88497,41.92283],[-69.96503,41.63717],[-70.64,41.475],[-71.12039,41.49445],[-71.86,41.32],[-72.295,41.27],[-72.87643,41.22065],[-73.71,40.931102],[-72.24126,41.11948],[-71.945,40.93],[-73.345,40.63],[-73.982,40.628],[-73.952325,40.75075],[-74.25671,40.47351],[-73.96244,40.42763],[-74.17838,39.70926],[-74.90604,38.93954],[-74.98041,39.1964],[-75.20002,39.24845],[-75.52805,39.4985],[-75.32,38.96],[-75.071835,38.782032],[-75.05673,38.40412],[-75.37747,38.01551],[-75.94023,37.21689],[-76.03127,37.2566],[-75.72205,37.93705],[-76.23287,38.319215],[-76.35,39.15],[-76.542725,38.717615],[-76.32933,38.08326],[-76.989998,38.239992],[-76.30162,37.917945],[-76.25874,36.9664],[-75.9718,36.89726],[-75.86804,36.55125],[-75.72749,35.55074],[-76.36318,34.80854],[-77.397635,34.51201],[-78.05496,33.92547],[-78.55435,33.86133],[-79.06067,33.49395],[-79.20357,33.15839],[-80.301325,32.509355],[-80.86498,32.0333],[-81.33629,31.44049],[-81.49042,30.72999],[-81.31371,30.03552],[-80.98,29.18],[-80.535585,28.47213],[-80.53,28.04],[-80.056539,26.88],[-80.088015,26.205765],[-80.13156,25.816775],[-80.38103,25.20616],[-80.68,25.08],[-81.17213,25.20126],[-81.33,25.64],[-81.71,25.87],[-82.24,26.73],[-82.70515,27.49504],[-82.85526,27.88624],[-82.65,28.55],[-82.93,29.1],[-83.70959,29.93656],[-84.1,30.09],[-85.10882,29.63615],[-85.28784,29.68612],[-85.7731,30.15261],[-86.4,30.4],[-87.53036,30.27433],[-88.41782,30.3849],[-89.18049,30.31598],[-89.593831,30.159994],[-89.413735,29.89419],[-89.43,29.48864],[-89.21767,29.29108],[-89.40823,29.15961],[-89.77928,29.30714],[-90.15463,29.11743],[-90.880225,29.148535],[-91.626785,29.677],[-92.49906,29.5523],[-93.22637,29.78375],[-93.84842,29.71363],[-94.69,29.48],[-95.60026,28.73863],[-96.59404,28.30748],[-97.14,27.83],[-97.37,27.38],[-97.38,26.69],[-97.33,26.21],[-97.14,25.87],[-97.53,25.84],[-98.24,26.06],[-99.02,26.37],[-99.3,26.84],[-99.52,27.54],[-100.11,28.11],[-100.45584,28.69612],[-100.9576,29.38071],[-101.6624,29.7793],[-102.48,29.76],[-103.11,28.97],[-103.94,29.27],[-104.45697,29.57196],[-104.70575,30.12173],[-105.03737,30.64402],[-105.63159,31.08383],[-106.1429,31.39995],[-106.50759,31.75452],[-108.24,31.754854],[-108.24194,31.34222],[-109.035,31.34194],[-111.02361,31.33472],[-113.30498,32.03914],[-114.815,32.52528],[-114.72139,32.72083],[-115.99135,32.61239],[-117.12776,32.53534],[-117.295938,33.046225],[-117.944,33.621236],[-118.410602,33.740909],[-118.519895,34.027782],[-119.081,34.078],[-119.438841,34.348477],[-120.36778,34.44711],[-120.62286,34.60855],[-120.74433,35.15686],[-121.71457,36.16153],[-122.54747,37.55176],[-122.51201,37.78339],[-122.95319,38.11371],[-123.7272,38.95166],[-123.86517,39.76699],[-124.39807,40.3132],[-124.17886,41.14202],[-124.2137,41.99964],[-124.53284,42.76599],[-124.14214,43.70838],[-124.020535,44.615895],[-123.89893,45.52341],[-124.079635,46.86475],[-124.39567,47.72017],[-124.68721,48.184433],[-124.566101,48.379715],[-123.12,48.04],[-122.58736,47.096],[-122.34,47.36],[-122.5,48.18],[-122.84,49],[-120,49],[-117.03121,49],[-116.04818,49],[-113,49],[-110.05,49],[-107.05,49],[-104.04826,48.99986],[-100.65,49],[-97.22872,49.0007],[-95.15907,49],[-95.15609,49.38425],[-94.81758,49.38905]]],[[[-153.006314,57.115842],[-154.00509,56.734677],[-154.516403,56.992749],[-154.670993,57.461196],[-153.76278,57.816575],[-153.228729,57.968968],[-152.564791,57.901427],[-152.141147,57.591059],[-153.006314,57.115842]]],[[[-165.579164,59.909987],[-166.19277,59.754441],[-166.848337,59.941406],[-167.455277,60.213069],[-166.467792,60.38417],[-165.67443,60.293607],[-165.579164,59.909987]]],[[[-171.731657,63.782515],[-171.114434,63.592191],[-170.491112,63.694975],[-169.682505,63.431116],[-168.689439,63.297506],[-168.771941,63.188598],[-169.52944,62.976931],[-170.290556,63.194438],[-170.671386,63.375822],[-171.553063,63.317789],[-171.791111,63.405846],[-171.731657,63.782515]]],[[[-155.06779,71.147776],[-154.344165,70.696409],[-153.900006,70.889989],[-152.210006,70.829992],[-152.270002,70.600006],[-150.739992,70.430017],[-149.720003,70.53001],[-147.613362,70.214035],[-145.68999,70.12001],[-144.920011,69.989992],[-143.589446,70.152514],[-142.07251,69.851938],[-140.985988,69.711998],[-140.992499,66.000029],[-140.99777,60.306397],[-140.012998,60.276838],[-139.039,60.000007],[-138.34089,59.56211],[-137.4525,58.905],[-136.47972,59.46389],[-135.47583,59.78778],[-134.945,59.27056],[-134.27111,58.86111],[-133.355549,58.410285],[-132.73042,57.69289],[-131.70781,56.55212],[-130.00778,55.91583],[-129.979994,55.284998],[-130.53611,54.802753],[-131.085818,55.178906],[-131.967211,55.497776],[-132.250011,56.369996],[-133.539181,57.178887],[-134.078063,58.123068],[-135.038211,58.187715],[-136.628062,58.212209],[-137.800006,58.499995],[-139.867787,59.537762],[-140.825274,59.727517],[-142.574444,60.084447],[-143.958881,59.99918],[-145.925557,60.45861],[-147.114374,60.884656],[-148.224306,60.672989],[-148.018066,59.978329],[-148.570823,59.914173],[-149.727858,59.705658],[-150.608243,59.368211],[-151.716393,59.155821],[-151.859433,59.744984],[-151.409719,60.725803],[-150.346941,61.033588],[-150.621111,61.284425],[-151.895839,60.727198],[-152.57833,60.061657],[-154.019172,59.350279],[-153.287511,58.864728],[-154.232492,58.146374],[-155.307491,57.727795],[-156.308335,57.422774],[-156.556097,56.979985],[-158.117217,56.463608],[-158.433321,55.994154],[-159.603327,55.566686],[-160.28972,55.643581],[-161.223048,55.364735],[-162.237766,55.024187],[-163.069447,54.689737],[-164.785569,54.404173],[-164.942226,54.572225],[-163.84834,55.039431],[-162.870001,55.348043],[-161.804175,55.894986],[-160.563605,56.008055],[-160.07056,56.418055],[-158.684443,57.016675],[-158.461097,57.216921],[-157.72277,57.570001],[-157.550274,58.328326],[-157.041675,58.918885],[-158.194731,58.615802],[-158.517218,58.787781],[-159.058606,58.424186],[-159.711667,58.93139],[-159.981289,58.572549],[-160.355271,59.071123],[-161.355003,58.670838],[-161.968894,58.671665],[-162.054987,59.266925],[-161.874171,59.633621],[-162.518059,59.989724],[-163.818341,59.798056],[-164.662218,60.267484],[-165.346388,60.507496],[-165.350832,61.073895],[-166.121379,61.500019],[-165.734452,62.074997],[-164.919179,62.633076],[-164.562508,63.146378],[-163.753332,63.219449],[-163.067224,63.059459],[-162.260555,63.541936],[-161.53445,63.455817],[-160.772507,63.766108],[-160.958335,64.222799],[-161.518068,64.402788],[-160.777778,64.788604],[-161.391926,64.777235],[-162.45305,64.559445],[-162.757786,64.338605],[-163.546394,64.55916],[-164.96083,64.446945],[-166.425288,64.686672],[-166.845004,65.088896],[-168.11056,65.669997],[-166.705271,66.088318],[-164.47471,66.57666],[-163.652512,66.57666],[-163.788602,66.077207],[-161.677774,66.11612],[-162.489715,66.735565],[-163.719717,67.116395],[-164.430991,67.616338],[-165.390287,68.042772],[-166.764441,68.358877],[-166.204707,68.883031],[-164.430811,68.915535],[-163.168614,69.371115],[-162.930566,69.858062],[-161.908897,70.33333],[-160.934797,70.44769],[-159.039176,70.891642],[-158.119723,70.824721],[-156.580825,71.357764],[-155.06779,71.147776]]]]}}, -{"type":"Feature","id":"UZB","properties":{"name":"Uzbekistan"},"geometry":{"type":"Polygon","coordinates":[[[66.518607,37.362784],[66.54615,37.974685],[65.215999,38.402695],[64.170223,38.892407],[63.518015,39.363257],[62.37426,40.053886],[61.882714,41.084857],[61.547179,41.26637],[60.465953,41.220327],[60.083341,41.425146],[59.976422,42.223082],[58.629011,42.751551],[57.78653,42.170553],[56.932215,41.826026],[57.096391,41.32231],[55.968191,41.308642],[55.928917,44.995858],[58.503127,45.586804],[58.689989,45.500014],[60.239972,44.784037],[61.05832,44.405817],[62.0133,43.504477],[63.185787,43.650075],[64.900824,43.728081],[66.098012,42.99766],[66.023392,41.994646],[66.510649,41.987644],[66.714047,41.168444],[67.985856,41.135991],[68.259896,40.662325],[68.632483,40.668681],[69.070027,41.384244],[70.388965,42.081308],[70.962315,42.266154],[71.259248,42.167711],[70.420022,41.519998],[71.157859,41.143587],[71.870115,41.3929],[73.055417,40.866033],[71.774875,40.145844],[71.014198,40.244366],[70.601407,40.218527],[70.45816,40.496495],[70.666622,40.960213],[69.329495,40.727824],[69.011633,40.086158],[68.536416,39.533453],[67.701429,39.580478],[67.44222,39.140144],[68.176025,38.901553],[68.392033,38.157025],[67.83,37.144994],[67.075782,37.356144],[66.518607,37.362784]]]}}, -{"type":"Feature","id":"VEN","properties":{"name":"Venezuela"},"geometry":{"type":"Polygon","coordinates":[[[-71.331584,11.776284],[-71.360006,11.539994],[-71.94705,11.423282],[-71.620868,10.96946],[-71.633064,10.446494],[-72.074174,9.865651],[-71.695644,9.072263],[-71.264559,9.137195],[-71.039999,9.859993],[-71.350084,10.211935],[-71.400623,10.968969],[-70.155299,11.375482],[-70.293843,11.846822],[-69.943245,12.162307],[-69.5843,11.459611],[-68.882999,11.443385],[-68.233271,10.885744],[-68.194127,10.554653],[-67.296249,10.545868],[-66.227864,10.648627],[-65.655238,10.200799],[-64.890452,10.077215],[-64.329479,10.389599],[-64.318007,10.641418],[-63.079322,10.701724],[-61.880946,10.715625],[-62.730119,10.420269],[-62.388512,9.948204],[-61.588767,9.873067],[-60.830597,9.38134],[-60.671252,8.580174],[-60.150096,8.602757],[-59.758285,8.367035],[-60.550588,7.779603],[-60.637973,7.415],[-60.295668,7.043911],[-60.543999,6.856584],[-61.159336,6.696077],[-61.139415,6.234297],[-61.410303,5.959068],[-60.733574,5.200277],[-60.601179,4.918098],[-60.966893,4.536468],[-62.08543,4.162124],[-62.804533,4.006965],[-63.093198,3.770571],[-63.888343,4.02053],[-64.628659,4.148481],[-64.816064,4.056445],[-64.368494,3.79721],[-64.408828,3.126786],[-64.269999,2.497006],[-63.422867,2.411068],[-63.368788,2.2009],[-64.083085,1.916369],[-64.199306,1.492855],[-64.611012,1.328731],[-65.354713,1.095282],[-65.548267,0.789254],[-66.325765,0.724452],[-66.876326,1.253361],[-67.181294,2.250638],[-67.447092,2.600281],[-67.809938,2.820655],[-67.303173,3.318454],[-67.337564,3.542342],[-67.621836,3.839482],[-67.823012,4.503937],[-67.744697,5.221129],[-67.521532,5.55687],[-67.34144,6.095468],[-67.695087,6.267318],[-68.265052,6.153268],[-68.985319,6.206805],[-69.38948,6.099861],[-70.093313,6.960376],[-70.674234,7.087785],[-71.960176,6.991615],[-72.198352,7.340431],[-72.444487,7.423785],[-72.479679,7.632506],[-72.360901,8.002638],[-72.439862,8.405275],[-72.660495,8.625288],[-72.78873,9.085027],[-73.304952,9.152],[-73.027604,9.73677],[-72.905286,10.450344],[-72.614658,10.821975],[-72.227575,11.108702],[-71.973922,11.608672],[-71.331584,11.776284]]]}}, -{"type":"Feature","id":"VNM","properties":{"name":"Vietnam"},"geometry":{"type":"Polygon","coordinates":[[[108.05018,21.55238],[106.715068,20.696851],[105.881682,19.75205],[105.662006,19.058165],[106.426817,18.004121],[107.361954,16.697457],[108.269495,16.079742],[108.877107,15.276691],[109.33527,13.426028],[109.200136,11.666859],[108.36613,11.008321],[107.220929,10.364484],[106.405113,9.53084],[105.158264,8.59976],[104.795185,9.241038],[105.076202,9.918491],[104.334335,10.486544],[105.199915,10.88931],[106.24967,10.961812],[105.810524,11.567615],[107.491403,12.337206],[107.614548,13.535531],[107.382727,14.202441],[107.564525,15.202173],[107.312706,15.908538],[106.556008,16.604284],[105.925762,17.485315],[105.094598,18.666975],[103.896532,19.265181],[104.183388,19.624668],[104.822574,19.886642],[104.435,20.758733],[103.203861,20.766562],[102.754896,21.675137],[102.170436,22.464753],[102.706992,22.708795],[103.504515,22.703757],[104.476858,22.81915],[105.329209,23.352063],[105.811247,22.976892],[106.725403,22.794268],[106.567273,22.218205],[107.04342,21.811899],[108.05018,21.55238]]]}}, -{"type":"Feature","id":"VUT","properties":{"name":"Vanuatu"},"geometry":{"type":"MultiPolygon","coordinates":[[[[167.844877,-16.466333],[167.515181,-16.59785],[167.180008,-16.159995],[167.216801,-15.891846],[167.844877,-16.466333]]],[[[167.107712,-14.93392],[167.270028,-15.740021],[167.001207,-15.614602],[166.793158,-15.668811],[166.649859,-15.392704],[166.629137,-14.626497],[167.107712,-14.93392]]]]}}, -{"type":"Feature","id":"PSE","properties":{"name":"West Bank"},"geometry":{"type":"Polygon","coordinates":[[[35.545665,32.393992],[35.545252,31.782505],[35.397561,31.489086],[34.927408,31.353435],[34.970507,31.616778],[35.225892,31.754341],[34.974641,31.866582],[35.18393,32.532511],[35.545665,32.393992]]]}}, -{"type":"Feature","id":"YEM","properties":{"name":"Yemen"},"geometry":{"type":"Polygon","coordinates":[[[53.108573,16.651051],[52.385206,16.382411],[52.191729,15.938433],[52.168165,15.59742],[51.172515,15.17525],[49.574576,14.708767],[48.679231,14.003202],[48.238947,13.94809],[47.938914,14.007233],[47.354454,13.59222],[46.717076,13.399699],[45.877593,13.347764],[45.62505,13.290946],[45.406459,13.026905],[45.144356,12.953938],[44.989533,12.699587],[44.494576,12.721653],[44.175113,12.58595],[43.482959,12.6368],[43.222871,13.22095],[43.251448,13.767584],[43.087944,14.06263],[42.892245,14.802249],[42.604873,15.213335],[42.805015,15.261963],[42.702438,15.718886],[42.823671,15.911742],[42.779332,16.347891],[43.218375,16.66689],[43.115798,17.08844],[43.380794,17.579987],[43.791519,17.319977],[44.062613,17.410359],[45.216651,17.433329],[45.399999,17.333335],[46.366659,17.233315],[46.749994,17.283338],[47.000005,16.949999],[47.466695,17.116682],[48.183344,18.166669],[49.116672,18.616668],[52.00001,19.000003],[52.782184,17.349742],[53.108573,16.651051]]]}}, -{"type":"Feature","id":"ZAF","properties":{"name":"South Africa"},"geometry":{"type":"Polygon","coordinates":[[[31.521001,-29.257387],[31.325561,-29.401978],[30.901763,-29.909957],[30.622813,-30.423776],[30.055716,-31.140269],[28.925553,-32.172041],[28.219756,-32.771953],[27.464608,-33.226964],[26.419452,-33.61495],[25.909664,-33.66704],[25.780628,-33.944646],[25.172862,-33.796851],[24.677853,-33.987176],[23.594043,-33.794474],[22.988189,-33.916431],[22.574157,-33.864083],[21.542799,-34.258839],[20.689053,-34.417175],[20.071261,-34.795137],[19.616405,-34.819166],[19.193278,-34.462599],[18.855315,-34.444306],[18.424643,-33.997873],[18.377411,-34.136521],[18.244499,-33.867752],[18.25008,-33.281431],[17.92519,-32.611291],[18.24791,-32.429131],[18.221762,-31.661633],[17.566918,-30.725721],[17.064416,-29.878641],[17.062918,-29.875954],[16.344977,-28.576705],[16.824017,-28.082162],[17.218929,-28.355943],[17.387497,-28.783514],[17.836152,-28.856378],[18.464899,-29.045462],[19.002127,-28.972443],[19.894734,-28.461105],[19.895768,-24.76779],[20.165726,-24.917962],[20.758609,-25.868136],[20.66647,-26.477453],[20.889609,-26.828543],[21.605896,-26.726534],[22.105969,-26.280256],[22.579532,-25.979448],[22.824271,-25.500459],[23.312097,-25.26869],[23.73357,-25.390129],[24.211267,-25.670216],[25.025171,-25.71967],[25.664666,-25.486816],[25.765849,-25.174845],[25.941652,-24.696373],[26.485753,-24.616327],[26.786407,-24.240691],[27.11941,-23.574323],[28.017236,-22.827754],[29.432188,-22.091313],[29.839037,-22.102216],[30.322883,-22.271612],[30.659865,-22.151567],[31.191409,-22.25151],[31.670398,-23.658969],[31.930589,-24.369417],[31.752408,-25.484284],[31.837778,-25.843332],[31.333158,-25.660191],[31.04408,-25.731452],[30.949667,-26.022649],[30.676609,-26.398078],[30.685962,-26.743845],[31.282773,-27.285879],[31.86806,-27.177927],[32.071665,-26.73382],[32.83012,-26.742192],[32.580265,-27.470158],[32.462133,-28.301011],[32.203389,-28.752405],[31.521001,-29.257387]],[[28.978263,-28.955597],[28.5417,-28.647502],[28.074338,-28.851469],[27.532511,-29.242711],[26.999262,-29.875954],[27.749397,-30.645106],[28.107205,-30.545732],[28.291069,-30.226217],[28.8484,-30.070051],[29.018415,-29.743766],[29.325166,-29.257387],[28.978263,-28.955597]]]}}, -{"type":"Feature","id":"ZMB","properties":{"name":"Zambia"},"geometry":{"type":"Polygon","coordinates":[[[32.759375,-9.230599],[33.231388,-9.676722],[33.485688,-10.525559],[33.31531,-10.79655],[33.114289,-11.607198],[33.306422,-12.435778],[32.991764,-12.783871],[32.688165,-13.712858],[33.214025,-13.97186],[30.179481,-14.796099],[30.274256,-15.507787],[29.516834,-15.644678],[28.947463,-16.043051],[28.825869,-16.389749],[28.467906,-16.4684],[27.598243,-17.290831],[27.044427,-17.938026],[26.706773,-17.961229],[26.381935,-17.846042],[25.264226,-17.73654],[25.084443,-17.661816],[25.07695,-17.578823],[24.682349,-17.353411],[24.033862,-17.295843],[23.215048,-17.523116],[22.562478,-16.898451],[21.887843,-16.08031],[21.933886,-12.898437],[24.016137,-12.911046],[23.930922,-12.565848],[24.079905,-12.191297],[23.904154,-11.722282],[24.017894,-11.237298],[23.912215,-10.926826],[24.257155,-10.951993],[24.314516,-11.262826],[24.78317,-11.238694],[25.418118,-11.330936],[25.75231,-11.784965],[26.553088,-11.92444],[27.16442,-11.608748],[27.388799,-12.132747],[28.155109,-12.272481],[28.523562,-12.698604],[28.934286,-13.248958],[29.699614,-13.257227],[29.616001,-12.178895],[29.341548,-12.360744],[28.642417,-11.971569],[28.372253,-11.793647],[28.49607,-10.789884],[28.673682,-9.605925],[28.449871,-9.164918],[28.734867,-8.526559],[29.002912,-8.407032],[30.346086,-8.238257],[30.740015,-8.340007],[31.157751,-8.594579],[31.556348,-8.762049],[32.191865,-8.930359],[32.759375,-9.230599]]]}}, -{"type":"Feature","id":"ZWE","properties":{"name":"Zimbabwe"},"geometry":{"type":"Polygon","coordinates":[[[31.191409,-22.25151],[30.659865,-22.151567],[30.322883,-22.271612],[29.839037,-22.102216],[29.432188,-22.091313],[28.794656,-21.639454],[28.02137,-21.485975],[27.727228,-20.851802],[27.724747,-20.499059],[27.296505,-20.39152],[26.164791,-19.293086],[25.850391,-18.714413],[25.649163,-18.536026],[25.264226,-17.73654],[26.381935,-17.846042],[26.706773,-17.961229],[27.044427,-17.938026],[27.598243,-17.290831],[28.467906,-16.4684],[28.825869,-16.389749],[28.947463,-16.043051],[29.516834,-15.644678],[30.274256,-15.507787],[30.338955,-15.880839],[31.173064,-15.860944],[31.636498,-16.07199],[31.852041,-16.319417],[32.328239,-16.392074],[32.847639,-16.713398],[32.849861,-17.979057],[32.654886,-18.67209],[32.611994,-19.419383],[32.772708,-19.715592],[32.659743,-20.30429],[32.508693,-20.395292],[32.244988,-21.116489],[31.191409,-22.25151]]]}} -]} diff --git a/projects/wave-core/assets/csv-data-sources.json b/projects/wave-core/assets/csv-data-sources.json deleted file mode 100644 index 6268ac74..00000000 --- a/projects/wave-core/assets/csv-data-sources.json +++ /dev/null @@ -1,69 +0,0 @@ -[ - { - "name": "South African weather sensors", - "filename": "datasources/idessa/dwd.ttx", - "params": { - "geometry": "xy", - "time": "start", - "on_error": "skip", - "time1_format": { - "format": "dmyhm" - }, - "duration": "inf", - "columns": { - "x": "Longitude", - "y": "Latitude", - "time1": "DateT", - "numeric": ["Rain"], - "textual": ["StasName"] - } - } - }, - { - "name": "Bush Density Survey, Christiaan Harmse (2011-2012)", - "filename": "datasources/idessa/bush_densities.csv", - "params": { - "geometry": "xy", - "time": "none", - "on_error": "skip", - "columns": { - "x": "x", - "y": "y", - "numeric": ["Woody plants ha-1", "Tree equivalents ha-1"], - "textual": ["Site name"] - } - } - }, - { - "name": "GBIF - Loxodonta cyclotis (Matschie, 1900)", - "filename": "datasources/gfbio/gbif-0004807-160822134323880.csv", - "params": { - "geometry": "xy", - "time": "none", - "on_error": "skip", - "separator": ";", - "columns": { - "x": "decimallongitude", - "y": "decimallatitude", - "numeric": ["gbifid"], - "textual": [ - "datasetkey", - "occurrenceid", - "kingdom", - "phylum", - "class", - "order", - "family", - "genus", - "species", - "infraspecificepithet", - "taxonrank", - "scientificname", - "countrycode", - "locality", - "publishingorgkey" - ] - } - } - } -] diff --git a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.eot b/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.eot deleted file mode 100644 index 70508eba..00000000 Binary files a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.eot and /dev/null differ diff --git a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.ijmap b/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.ijmap deleted file mode 100644 index d9f1d259..00000000 --- a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.ijmap +++ /dev/null @@ -1 +0,0 @@ -{"icons":{"e84d":{"name":"3d Rotation"},"eb3b":{"name":"Ac Unit"},"e190":{"name":"Access Alarm"},"e191":{"name":"Access Alarms"},"e192":{"name":"Access Time"},"e84e":{"name":"Accessibility"},"e914":{"name":"Accessible"},"e84f":{"name":"Account Balance"},"e850":{"name":"Account Balance Wallet"},"e851":{"name":"Account Box"},"e853":{"name":"Account Circle"},"e60e":{"name":"Adb"},"e145":{"name":"Add"},"e439":{"name":"Add A Photo"},"e193":{"name":"Add Alarm"},"e003":{"name":"Add Alert"},"e146":{"name":"Add Box"},"e147":{"name":"Add Circle"},"e148":{"name":"Add Circle Outline"},"e567":{"name":"Add Location"},"e854":{"name":"Add Shopping Cart"},"e39d":{"name":"Add To Photos"},"e05c":{"name":"Add To Queue"},"e39e":{"name":"Adjust"},"e630":{"name":"Airline Seat Flat"},"e631":{"name":"Airline Seat Flat Angled"},"e632":{"name":"Airline Seat Individual Suite"},"e633":{"name":"Airline Seat Legroom Extra"},"e634":{"name":"Airline Seat Legroom Normal"},"e635":{"name":"Airline Seat Legroom Reduced"},"e636":{"name":"Airline Seat Recline Extra"},"e637":{"name":"Airline Seat Recline Normal"},"e195":{"name":"Airplanemode Active"},"e194":{"name":"Airplanemode Inactive"},"e055":{"name":"Airplay"},"eb3c":{"name":"Airport Shuttle"},"e855":{"name":"Alarm"},"e856":{"name":"Alarm Add"},"e857":{"name":"Alarm Off"},"e858":{"name":"Alarm On"},"e019":{"name":"Album"},"eb3d":{"name":"All Inclusive"},"e90b":{"name":"All Out"},"e859":{"name":"Android"},"e85a":{"name":"Announcement"},"e5c3":{"name":"Apps"},"e149":{"name":"Archive"},"e5c4":{"name":"Arrow Back"},"e5db":{"name":"Arrow Downward"},"e5c5":{"name":"Arrow Drop Down"},"e5c6":{"name":"Arrow Drop Down Circle"},"e5c7":{"name":"Arrow Drop Up"},"e5c8":{"name":"Arrow Forward"},"e5d8":{"name":"Arrow Upward"},"e060":{"name":"Art Track"},"e85b":{"name":"Aspect Ratio"},"e85c":{"name":"Assessment"},"e85d":{"name":"Assignment"},"e85e":{"name":"Assignment Ind"},"e85f":{"name":"Assignment Late"},"e860":{"name":"Assignment Return"},"e861":{"name":"Assignment Returned"},"e862":{"name":"Assignment Turned In"},"e39f":{"name":"Assistant"},"e3a0":{"name":"Assistant Photo"},"e226":{"name":"Attach File"},"e227":{"name":"Attach Money"},"e2bc":{"name":"Attachment"},"e3a1":{"name":"Audiotrack"},"e863":{"name":"Autorenew"},"e01b":{"name":"Av Timer"},"e14a":{"name":"Backspace"},"e864":{"name":"Backup"},"e19c":{"name":"Battery Alert"},"e1a3":{"name":"Battery Charging Full"},"e1a4":{"name":"Battery Full"},"e1a5":{"name":"Battery Std"},"e1a6":{"name":"Battery Unknown"},"eb3e":{"name":"Beach Access"},"e52d":{"name":"Beenhere"},"e14b":{"name":"Block"},"e1a7":{"name":"Bluetooth"},"e60f":{"name":"Bluetooth Audio"},"e1a8":{"name":"Bluetooth Connected"},"e1a9":{"name":"Bluetooth Disabled"},"e1aa":{"name":"Bluetooth Searching"},"e3a2":{"name":"Blur Circular"},"e3a3":{"name":"Blur Linear"},"e3a4":{"name":"Blur Off"},"e3a5":{"name":"Blur On"},"e865":{"name":"Book"},"e866":{"name":"Bookmark"},"e867":{"name":"Bookmark Border"},"e228":{"name":"Border All"},"e229":{"name":"Border Bottom"},"e22a":{"name":"Border Clear"},"e22b":{"name":"Border Color"},"e22c":{"name":"Border Horizontal"},"e22d":{"name":"Border Inner"},"e22e":{"name":"Border Left"},"e22f":{"name":"Border Outer"},"e230":{"name":"Border Right"},"e231":{"name":"Border Style"},"e232":{"name":"Border Top"},"e233":{"name":"Border Vertical"},"e06b":{"name":"Branding Watermark"},"e3a6":{"name":"Brightness 1"},"e3a7":{"name":"Brightness 2"},"e3a8":{"name":"Brightness 3"},"e3a9":{"name":"Brightness 4"},"e3aa":{"name":"Brightness 5"},"e3ab":{"name":"Brightness 6"},"e3ac":{"name":"Brightness 7"},"e1ab":{"name":"Brightness Auto"},"e1ac":{"name":"Brightness High"},"e1ad":{"name":"Brightness Low"},"e1ae":{"name":"Brightness Medium"},"e3ad":{"name":"Broken Image"},"e3ae":{"name":"Brush"},"e6dd":{"name":"Bubble Chart"},"e868":{"name":"Bug Report"},"e869":{"name":"Build"},"e43c":{"name":"Burst Mode"},"e0af":{"name":"Business"},"eb3f":{"name":"Business Center"},"e86a":{"name":"Cached"},"e7e9":{"name":"Cake"},"e0b0":{"name":"Call"},"e0b1":{"name":"Call End"},"e0b2":{"name":"Call Made"},"e0b3":{"name":"Call Merge"},"e0b4":{"name":"Call Missed"},"e0e4":{"name":"Call Missed Outgoing"},"e0b5":{"name":"Call Received"},"e0b6":{"name":"Call Split"},"e06c":{"name":"Call To Action"},"e3af":{"name":"Camera"},"e3b0":{"name":"Camera Alt"},"e8fc":{"name":"Camera Enhance"},"e3b1":{"name":"Camera Front"},"e3b2":{"name":"Camera Rear"},"e3b3":{"name":"Camera Roll"},"e5c9":{"name":"Cancel"},"e8f6":{"name":"Card Giftcard"},"e8f7":{"name":"Card Membership"},"e8f8":{"name":"Card Travel"},"eb40":{"name":"Casino"},"e307":{"name":"Cast"},"e308":{"name":"Cast Connected"},"e3b4":{"name":"Center Focus Strong"},"e3b5":{"name":"Center Focus Weak"},"e86b":{"name":"Change History"},"e0b7":{"name":"Chat"},"e0ca":{"name":"Chat Bubble"},"e0cb":{"name":"Chat Bubble Outline"},"e5ca":{"name":"Check"},"e834":{"name":"Check Box"},"e835":{"name":"Check Box Outline Blank"},"e86c":{"name":"Check Circle"},"e5cb":{"name":"Chevron Left"},"e5cc":{"name":"Chevron Right"},"eb41":{"name":"Child Care"},"eb42":{"name":"Child Friendly"},"e86d":{"name":"Chrome Reader Mode"},"e86e":{"name":"Class"},"e14c":{"name":"Clear"},"e0b8":{"name":"Clear All"},"e5cd":{"name":"Close"},"e01c":{"name":"Closed Caption"},"e2bd":{"name":"Cloud"},"e2be":{"name":"Cloud Circle"},"e2bf":{"name":"Cloud Done"},"e2c0":{"name":"Cloud Download"},"e2c1":{"name":"Cloud Off"},"e2c2":{"name":"Cloud Queue"},"e2c3":{"name":"Cloud Upload"},"e86f":{"name":"Code"},"e3b6":{"name":"Collections"},"e431":{"name":"Collections Bookmark"},"e3b7":{"name":"Color Lens"},"e3b8":{"name":"Colorize"},"e0b9":{"name":"Comment"},"e3b9":{"name":"Compare"},"e915":{"name":"Compare Arrows"},"e30a":{"name":"Computer"},"e638":{"name":"Confirmation Number"},"e0d0":{"name":"Contact Mail"},"e0cf":{"name":"Contact Phone"},"e0ba":{"name":"Contacts"},"e14d":{"name":"Content Copy"},"e14e":{"name":"Content Cut"},"e14f":{"name":"Content Paste"},"e3ba":{"name":"Control Point"},"e3bb":{"name":"Control Point Duplicate"},"e90c":{"name":"Copyright"},"e150":{"name":"Create"},"e2cc":{"name":"Create New Folder"},"e870":{"name":"Credit Card"},"e3be":{"name":"Crop"},"e3bc":{"name":"Crop 16 9"},"e3bd":{"name":"Crop 3 2"},"e3bf":{"name":"Crop 5 4"},"e3c0":{"name":"Crop 7 5"},"e3c1":{"name":"Crop Din"},"e3c2":{"name":"Crop Free"},"e3c3":{"name":"Crop Landscape"},"e3c4":{"name":"Crop Original"},"e3c5":{"name":"Crop Portrait"},"e437":{"name":"Crop Rotate"},"e3c6":{"name":"Crop Square"},"e871":{"name":"Dashboard"},"e1af":{"name":"Data Usage"},"e916":{"name":"Date Range"},"e3c7":{"name":"Dehaze"},"e872":{"name":"Delete"},"e92b":{"name":"Delete Forever"},"e16c":{"name":"Delete Sweep"},"e873":{"name":"Description"},"e30b":{"name":"Desktop Mac"},"e30c":{"name":"Desktop Windows"},"e3c8":{"name":"Details"},"e30d":{"name":"Developer Board"},"e1b0":{"name":"Developer Mode"},"e335":{"name":"Device Hub"},"e1b1":{"name":"Devices"},"e337":{"name":"Devices Other"},"e0bb":{"name":"Dialer Sip"},"e0bc":{"name":"Dialpad"},"e52e":{"name":"Directions"},"e52f":{"name":"Directions Bike"},"e532":{"name":"Directions Boat"},"e530":{"name":"Directions Bus"},"e531":{"name":"Directions Car"},"e534":{"name":"Directions Railway"},"e566":{"name":"Directions Run"},"e533":{"name":"Directions Subway"},"e535":{"name":"Directions Transit"},"e536":{"name":"Directions Walk"},"e610":{"name":"Disc Full"},"e875":{"name":"Dns"},"e612":{"name":"Do Not Disturb"},"e611":{"name":"Do Not Disturb Alt"},"e643":{"name":"Do Not Disturb Off"},"e644":{"name":"Do Not Disturb On"},"e30e":{"name":"Dock"},"e7ee":{"name":"Domain"},"e876":{"name":"Done"},"e877":{"name":"Done All"},"e917":{"name":"Donut Large"},"e918":{"name":"Donut Small"},"e151":{"name":"Drafts"},"e25d":{"name":"Drag Handle"},"e613":{"name":"Drive Eta"},"e1b2":{"name":"Dvr"},"e3c9":{"name":"Edit"},"e568":{"name":"Edit Location"},"e8fb":{"name":"Eject"},"e0be":{"name":"Email"},"e63f":{"name":"Enhanced Encryption"},"e01d":{"name":"Equalizer"},"e000":{"name":"Error"},"e001":{"name":"Error Outline"},"e926":{"name":"Euro Symbol"},"e56d":{"name":"Ev Station"},"e878":{"name":"Event"},"e614":{"name":"Event Available"},"e615":{"name":"Event Busy"},"e616":{"name":"Event Note"},"e903":{"name":"Event Seat"},"e879":{"name":"Exit To App"},"e5ce":{"name":"Expand Less"},"e5cf":{"name":"Expand More"},"e01e":{"name":"Explicit"},"e87a":{"name":"Explore"},"e3ca":{"name":"Exposure"},"e3cb":{"name":"Exposure Neg 1"},"e3cc":{"name":"Exposure Neg 2"},"e3cd":{"name":"Exposure Plus 1"},"e3ce":{"name":"Exposure Plus 2"},"e3cf":{"name":"Exposure Zero"},"e87b":{"name":"Extension"},"e87c":{"name":"Face"},"e01f":{"name":"Fast Forward"},"e020":{"name":"Fast Rewind"},"e87d":{"name":"Favorite"},"e87e":{"name":"Favorite Border"},"e06d":{"name":"Featured Play List"},"e06e":{"name":"Featured Video"},"e87f":{"name":"Feedback"},"e05d":{"name":"Fiber Dvr"},"e061":{"name":"Fiber Manual Record"},"e05e":{"name":"Fiber New"},"e06a":{"name":"Fiber Pin"},"e062":{"name":"Fiber Smart Record"},"e2c4":{"name":"File Download"},"e2c6":{"name":"File Upload"},"e3d3":{"name":"Filter"},"e3d0":{"name":"Filter 1"},"e3d1":{"name":"Filter 2"},"e3d2":{"name":"Filter 3"},"e3d4":{"name":"Filter 4"},"e3d5":{"name":"Filter 5"},"e3d6":{"name":"Filter 6"},"e3d7":{"name":"Filter 7"},"e3d8":{"name":"Filter 8"},"e3d9":{"name":"Filter 9"},"e3da":{"name":"Filter 9 Plus"},"e3db":{"name":"Filter B And W"},"e3dc":{"name":"Filter Center Focus"},"e3dd":{"name":"Filter Drama"},"e3de":{"name":"Filter Frames"},"e3df":{"name":"Filter Hdr"},"e152":{"name":"Filter List"},"e3e0":{"name":"Filter None"},"e3e2":{"name":"Filter Tilt Shift"},"e3e3":{"name":"Filter Vintage"},"e880":{"name":"Find In Page"},"e881":{"name":"Find Replace"},"e90d":{"name":"Fingerprint"},"e5dc":{"name":"First Page"},"eb43":{"name":"Fitness Center"},"e153":{"name":"Flag"},"e3e4":{"name":"Flare"},"e3e5":{"name":"Flash Auto"},"e3e6":{"name":"Flash Off"},"e3e7":{"name":"Flash On"},"e539":{"name":"Flight"},"e904":{"name":"Flight Land"},"e905":{"name":"Flight Takeoff"},"e3e8":{"name":"Flip"},"e882":{"name":"Flip To Back"},"e883":{"name":"Flip To Front"},"e2c7":{"name":"Folder"},"e2c8":{"name":"Folder Open"},"e2c9":{"name":"Folder Shared"},"e617":{"name":"Folder Special"},"e167":{"name":"Font Download"},"e234":{"name":"Format Align Center"},"e235":{"name":"Format Align Justify"},"e236":{"name":"Format Align Left"},"e237":{"name":"Format Align Right"},"e238":{"name":"Format Bold"},"e239":{"name":"Format Clear"},"e23a":{"name":"Format Color Fill"},"e23b":{"name":"Format Color Reset"},"e23c":{"name":"Format Color Text"},"e23d":{"name":"Format Indent Decrease"},"e23e":{"name":"Format Indent Increase"},"e23f":{"name":"Format Italic"},"e240":{"name":"Format Line Spacing"},"e241":{"name":"Format List Bulleted"},"e242":{"name":"Format List Numbered"},"e243":{"name":"Format Paint"},"e244":{"name":"Format Quote"},"e25e":{"name":"Format Shapes"},"e245":{"name":"Format Size"},"e246":{"name":"Format Strikethrough"},"e247":{"name":"Format Textdirection L To R"},"e248":{"name":"Format Textdirection R To L"},"e249":{"name":"Format Underlined"},"e0bf":{"name":"Forum"},"e154":{"name":"Forward"},"e056":{"name":"Forward 10"},"e057":{"name":"Forward 30"},"e058":{"name":"Forward 5"},"eb44":{"name":"Free Breakfast"},"e5d0":{"name":"Fullscreen"},"e5d1":{"name":"Fullscreen Exit"},"e24a":{"name":"Functions"},"e927":{"name":"G Translate"},"e30f":{"name":"Gamepad"},"e021":{"name":"Games"},"e90e":{"name":"Gavel"},"e155":{"name":"Gesture"},"e884":{"name":"Get App"},"e908":{"name":"Gif"},"eb45":{"name":"Golf Course"},"e1b3":{"name":"Gps Fixed"},"e1b4":{"name":"Gps Not Fixed"},"e1b5":{"name":"Gps Off"},"e885":{"name":"Grade"},"e3e9":{"name":"Gradient"},"e3ea":{"name":"Grain"},"e1b8":{"name":"Graphic Eq"},"e3eb":{"name":"Grid Off"},"e3ec":{"name":"Grid On"},"e7ef":{"name":"Group"},"e7f0":{"name":"Group Add"},"e886":{"name":"Group Work"},"e052":{"name":"Hd"},"e3ed":{"name":"Hdr Off"},"e3ee":{"name":"Hdr On"},"e3f1":{"name":"Hdr Strong"},"e3f2":{"name":"Hdr Weak"},"e310":{"name":"Headset"},"e311":{"name":"Headset Mic"},"e3f3":{"name":"Healing"},"e023":{"name":"Hearing"},"e887":{"name":"Help"},"e8fd":{"name":"Help Outline"},"e024":{"name":"High Quality"},"e25f":{"name":"Highlight"},"e888":{"name":"Highlight Off"},"e889":{"name":"History"},"e88a":{"name":"Home"},"eb46":{"name":"Hot Tub"},"e53a":{"name":"Hotel"},"e88b":{"name":"Hourglass Empty"},"e88c":{"name":"Hourglass Full"},"e902":{"name":"Http"},"e88d":{"name":"Https"},"e3f4":{"name":"Image"},"e3f5":{"name":"Image Aspect Ratio"},"e0e0":{"name":"Import Contacts"},"e0c3":{"name":"Import Export"},"e912":{"name":"Important Devices"},"e156":{"name":"Inbox"},"e909":{"name":"Indeterminate Check Box"},"e88e":{"name":"Info"},"e88f":{"name":"Info Outline"},"e890":{"name":"Input"},"e24b":{"name":"Insert Chart"},"e24c":{"name":"Insert Comment"},"e24d":{"name":"Insert Drive File"},"e24e":{"name":"Insert Emoticon"},"e24f":{"name":"Insert Invitation"},"e250":{"name":"Insert Link"},"e251":{"name":"Insert Photo"},"e891":{"name":"Invert Colors"},"e0c4":{"name":"Invert Colors Off"},"e3f6":{"name":"Iso"},"e312":{"name":"Keyboard"},"e313":{"name":"Keyboard Arrow Down"},"e314":{"name":"Keyboard Arrow Left"},"e315":{"name":"Keyboard Arrow Right"},"e316":{"name":"Keyboard Arrow Up"},"e317":{"name":"Keyboard Backspace"},"e318":{"name":"Keyboard Capslock"},"e31a":{"name":"Keyboard Hide"},"e31b":{"name":"Keyboard Return"},"e31c":{"name":"Keyboard Tab"},"e31d":{"name":"Keyboard Voice"},"eb47":{"name":"Kitchen"},"e892":{"name":"Label"},"e893":{"name":"Label Outline"},"e3f7":{"name":"Landscape"},"e894":{"name":"Language"},"e31e":{"name":"Laptop"},"e31f":{"name":"Laptop Chromebook"},"e320":{"name":"Laptop Mac"},"e321":{"name":"Laptop Windows"},"e5dd":{"name":"Last Page"},"e895":{"name":"Launch"},"e53b":{"name":"Layers"},"e53c":{"name":"Layers Clear"},"e3f8":{"name":"Leak Add"},"e3f9":{"name":"Leak Remove"},"e3fa":{"name":"Lens"},"e02e":{"name":"Library Add"},"e02f":{"name":"Library Books"},"e030":{"name":"Library Music"},"e90f":{"name":"Lightbulb Outline"},"e919":{"name":"Line Style"},"e91a":{"name":"Line Weight"},"e260":{"name":"Linear Scale"},"e157":{"name":"Link"},"e438":{"name":"Linked Camera"},"e896":{"name":"List"},"e0c6":{"name":"Live Help"},"e639":{"name":"Live Tv"},"e53f":{"name":"Local Activity"},"e53d":{"name":"Local Airport"},"e53e":{"name":"Local Atm"},"e540":{"name":"Local Bar"},"e541":{"name":"Local Cafe"},"e542":{"name":"Local Car Wash"},"e543":{"name":"Local Convenience Store"},"e556":{"name":"Local Dining"},"e544":{"name":"Local Drink"},"e545":{"name":"Local Florist"},"e546":{"name":"Local Gas Station"},"e547":{"name":"Local Grocery Store"},"e548":{"name":"Local Hospital"},"e549":{"name":"Local Hotel"},"e54a":{"name":"Local Laundry Service"},"e54b":{"name":"Local Library"},"e54c":{"name":"Local Mall"},"e54d":{"name":"Local Movies"},"e54e":{"name":"Local Offer"},"e54f":{"name":"Local Parking"},"e550":{"name":"Local Pharmacy"},"e551":{"name":"Local Phone"},"e552":{"name":"Local Pizza"},"e553":{"name":"Local Play"},"e554":{"name":"Local Post Office"},"e555":{"name":"Local Printshop"},"e557":{"name":"Local See"},"e558":{"name":"Local Shipping"},"e559":{"name":"Local Taxi"},"e7f1":{"name":"Location City"},"e1b6":{"name":"Location Disabled"},"e0c7":{"name":"Location Off"},"e0c8":{"name":"Location On"},"e1b7":{"name":"Location Searching"},"e897":{"name":"Lock"},"e898":{"name":"Lock Open"},"e899":{"name":"Lock Outline"},"e3fc":{"name":"Looks"},"e3fb":{"name":"Looks 3"},"e3fd":{"name":"Looks 4"},"e3fe":{"name":"Looks 5"},"e3ff":{"name":"Looks 6"},"e400":{"name":"Looks One"},"e401":{"name":"Looks Two"},"e028":{"name":"Loop"},"e402":{"name":"Loupe"},"e16d":{"name":"Low Priority"},"e89a":{"name":"Loyalty"},"e158":{"name":"Mail"},"e0e1":{"name":"Mail Outline"},"e55b":{"name":"Map"},"e159":{"name":"Markunread"},"e89b":{"name":"Markunread Mailbox"},"e322":{"name":"Memory"},"e5d2":{"name":"Menu"},"e252":{"name":"Merge Type"},"e0c9":{"name":"Message"},"e029":{"name":"Mic"},"e02a":{"name":"Mic None"},"e02b":{"name":"Mic Off"},"e618":{"name":"Mms"},"e253":{"name":"Mode Comment"},"e254":{"name":"Mode Edit"},"e263":{"name":"Monetization On"},"e25c":{"name":"Money Off"},"e403":{"name":"Monochrome Photos"},"e7f2":{"name":"Mood"},"e7f3":{"name":"Mood Bad"},"e619":{"name":"More"},"e5d3":{"name":"More Horiz"},"e5d4":{"name":"More Vert"},"e91b":{"name":"Motorcycle"},"e323":{"name":"Mouse"},"e168":{"name":"Move To Inbox"},"e02c":{"name":"Movie"},"e404":{"name":"Movie Creation"},"e43a":{"name":"Movie Filter"},"e6df":{"name":"Multiline Chart"},"e405":{"name":"Music Note"},"e063":{"name":"Music Video"},"e55c":{"name":"My Location"},"e406":{"name":"Nature"},"e407":{"name":"Nature People"},"e408":{"name":"Navigate Before"},"e409":{"name":"Navigate Next"},"e55d":{"name":"Navigation"},"e569":{"name":"Near Me"},"e1b9":{"name":"Network Cell"},"e640":{"name":"Network Check"},"e61a":{"name":"Network Locked"},"e1ba":{"name":"Network Wifi"},"e031":{"name":"New Releases"},"e16a":{"name":"Next Week"},"e1bb":{"name":"Nfc"},"e641":{"name":"No Encryption"},"e0cc":{"name":"No Sim"},"e033":{"name":"Not Interested"},"e06f":{"name":"Note"},"e89c":{"name":"Note Add"},"e7f4":{"name":"Notifications"},"e7f7":{"name":"Notifications Active"},"e7f5":{"name":"Notifications None"},"e7f6":{"name":"Notifications Off"},"e7f8":{"name":"Notifications Paused"},"e90a":{"name":"Offline Pin"},"e63a":{"name":"Ondemand Video"},"e91c":{"name":"Opacity"},"e89d":{"name":"Open In Browser"},"e89e":{"name":"Open In New"},"e89f":{"name":"Open With"},"e7f9":{"name":"Pages"},"e8a0":{"name":"Pageview"},"e40a":{"name":"Palette"},"e925":{"name":"Pan Tool"},"e40b":{"name":"Panorama"},"e40c":{"name":"Panorama Fish Eye"},"e40d":{"name":"Panorama Horizontal"},"e40e":{"name":"Panorama Vertical"},"e40f":{"name":"Panorama Wide Angle"},"e7fa":{"name":"Party Mode"},"e034":{"name":"Pause"},"e035":{"name":"Pause Circle Filled"},"e036":{"name":"Pause Circle Outline"},"e8a1":{"name":"Payment"},"e7fb":{"name":"People"},"e7fc":{"name":"People Outline"},"e8a2":{"name":"Perm Camera Mic"},"e8a3":{"name":"Perm Contact Calendar"},"e8a4":{"name":"Perm Data Setting"},"e8a5":{"name":"Perm Device Information"},"e8a6":{"name":"Perm Identity"},"e8a7":{"name":"Perm Media"},"e8a8":{"name":"Perm Phone Msg"},"e8a9":{"name":"Perm Scan Wifi"},"e7fd":{"name":"Person"},"e7fe":{"name":"Person Add"},"e7ff":{"name":"Person Outline"},"e55a":{"name":"Person Pin"},"e56a":{"name":"Person Pin Circle"},"e63b":{"name":"Personal Video"},"e91d":{"name":"Pets"},"e0cd":{"name":"Phone"},"e324":{"name":"Phone Android"},"e61b":{"name":"Phone Bluetooth Speaker"},"e61c":{"name":"Phone Forwarded"},"e61d":{"name":"Phone In Talk"},"e325":{"name":"Phone Iphone"},"e61e":{"name":"Phone Locked"},"e61f":{"name":"Phone Missed"},"e620":{"name":"Phone Paused"},"e326":{"name":"Phonelink"},"e0db":{"name":"Phonelink Erase"},"e0dc":{"name":"Phonelink Lock"},"e327":{"name":"Phonelink Off"},"e0dd":{"name":"Phonelink Ring"},"e0de":{"name":"Phonelink Setup"},"e410":{"name":"Photo"},"e411":{"name":"Photo Album"},"e412":{"name":"Photo Camera"},"e43b":{"name":"Photo Filter"},"e413":{"name":"Photo Library"},"e432":{"name":"Photo Size Select Actual"},"e433":{"name":"Photo Size Select Large"},"e434":{"name":"Photo Size Select Small"},"e415":{"name":"Picture As Pdf"},"e8aa":{"name":"Picture In Picture"},"e911":{"name":"Picture In Picture Alt"},"e6c4":{"name":"Pie Chart"},"e6c5":{"name":"Pie Chart Outlined"},"e55e":{"name":"Pin Drop"},"e55f":{"name":"Place"},"e037":{"name":"Play Arrow"},"e038":{"name":"Play Circle Filled"},"e039":{"name":"Play Circle Outline"},"e906":{"name":"Play For Work"},"e03b":{"name":"Playlist Add"},"e065":{"name":"Playlist Add Check"},"e05f":{"name":"Playlist Play"},"e800":{"name":"Plus One"},"e801":{"name":"Poll"},"e8ab":{"name":"Polymer"},"eb48":{"name":"Pool"},"e0ce":{"name":"Portable Wifi Off"},"e416":{"name":"Portrait"},"e63c":{"name":"Power"},"e336":{"name":"Power Input"},"e8ac":{"name":"Power Settings New"},"e91e":{"name":"Pregnant Woman"},"e0df":{"name":"Present To All"},"e8ad":{"name":"Print"},"e645":{"name":"Priority High"},"e80b":{"name":"Public"},"e255":{"name":"Publish"},"e8ae":{"name":"Query Builder"},"e8af":{"name":"Question Answer"},"e03c":{"name":"Queue"},"e03d":{"name":"Queue Music"},"e066":{"name":"Queue Play Next"},"e03e":{"name":"Radio"},"e837":{"name":"Radio Button Checked"},"e836":{"name":"Radio Button Unchecked"},"e560":{"name":"Rate Review"},"e8b0":{"name":"Receipt"},"e03f":{"name":"Recent Actors"},"e91f":{"name":"Record Voice Over"},"e8b1":{"name":"Redeem"},"e15a":{"name":"Redo"},"e5d5":{"name":"Refresh"},"e15b":{"name":"Remove"},"e15c":{"name":"Remove Circle"},"e15d":{"name":"Remove Circle Outline"},"e067":{"name":"Remove From Queue"},"e417":{"name":"Remove Red Eye"},"e928":{"name":"Remove Shopping Cart"},"e8fe":{"name":"Reorder"},"e040":{"name":"Repeat"},"e041":{"name":"Repeat One"},"e042":{"name":"Replay"},"e059":{"name":"Replay 10"},"e05a":{"name":"Replay 30"},"e05b":{"name":"Replay 5"},"e15e":{"name":"Reply"},"e15f":{"name":"Reply All"},"e160":{"name":"Report"},"e8b2":{"name":"Report Problem"},"e56c":{"name":"Restaurant"},"e561":{"name":"Restaurant Menu"},"e8b3":{"name":"Restore"},"e929":{"name":"Restore Page"},"e0d1":{"name":"Ring Volume"},"e8b4":{"name":"Room"},"eb49":{"name":"Room Service"},"e418":{"name":"Rotate 90 Degrees Ccw"},"e419":{"name":"Rotate Left"},"e41a":{"name":"Rotate Right"},"e920":{"name":"Rounded Corner"},"e328":{"name":"Router"},"e921":{"name":"Rowing"},"e0e5":{"name":"Rss Feed"},"e642":{"name":"Rv Hookup"},"e562":{"name":"Satellite"},"e161":{"name":"Save"},"e329":{"name":"Scanner"},"e8b5":{"name":"Schedule"},"e80c":{"name":"School"},"e1be":{"name":"Screen Lock Landscape"},"e1bf":{"name":"Screen Lock Portrait"},"e1c0":{"name":"Screen Lock Rotation"},"e1c1":{"name":"Screen Rotation"},"e0e2":{"name":"Screen Share"},"e623":{"name":"Sd Card"},"e1c2":{"name":"Sd Storage"},"e8b6":{"name":"Search"},"e32a":{"name":"Security"},"e162":{"name":"Select All"},"e163":{"name":"Send"},"e811":{"name":"Sentiment Dissatisfied"},"e812":{"name":"Sentiment Neutral"},"e813":{"name":"Sentiment Satisfied"},"e814":{"name":"Sentiment Very Dissatisfied"},"e815":{"name":"Sentiment Very Satisfied"},"e8b8":{"name":"Settings"},"e8b9":{"name":"Settings Applications"},"e8ba":{"name":"Settings Backup Restore"},"e8bb":{"name":"Settings Bluetooth"},"e8bd":{"name":"Settings Brightness"},"e8bc":{"name":"Settings Cell"},"e8be":{"name":"Settings Ethernet"},"e8bf":{"name":"Settings Input Antenna"},"e8c0":{"name":"Settings Input Component"},"e8c1":{"name":"Settings Input Composite"},"e8c2":{"name":"Settings Input Hdmi"},"e8c3":{"name":"Settings Input Svideo"},"e8c4":{"name":"Settings Overscan"},"e8c5":{"name":"Settings Phone"},"e8c6":{"name":"Settings Power"},"e8c7":{"name":"Settings Remote"},"e1c3":{"name":"Settings System Daydream"},"e8c8":{"name":"Settings Voice"},"e80d":{"name":"Share"},"e8c9":{"name":"Shop"},"e8ca":{"name":"Shop Two"},"e8cb":{"name":"Shopping Basket"},"e8cc":{"name":"Shopping Cart"},"e261":{"name":"Short Text"},"e6e1":{"name":"Show Chart"},"e043":{"name":"Shuffle"},"e1c8":{"name":"Signal Cellular 4 Bar"},"e1cd":{"name":"Signal Cellular Connected No Internet 4 Bar"},"e1ce":{"name":"Signal Cellular No Sim"},"e1cf":{"name":"Signal Cellular Null"},"e1d0":{"name":"Signal Cellular Off"},"e1d8":{"name":"Signal Wifi 4 Bar"},"e1d9":{"name":"Signal Wifi 4 Bar Lock"},"e1da":{"name":"Signal Wifi Off"},"e32b":{"name":"Sim Card"},"e624":{"name":"Sim Card Alert"},"e044":{"name":"Skip Next"},"e045":{"name":"Skip Previous"},"e41b":{"name":"Slideshow"},"e068":{"name":"Slow Motion Video"},"e32c":{"name":"Smartphone"},"eb4a":{"name":"Smoke Free"},"eb4b":{"name":"Smoking Rooms"},"e625":{"name":"Sms"},"e626":{"name":"Sms Failed"},"e046":{"name":"Snooze"},"e164":{"name":"Sort"},"e053":{"name":"Sort By Alpha"},"eb4c":{"name":"Spa"},"e256":{"name":"Space Bar"},"e32d":{"name":"Speaker"},"e32e":{"name":"Speaker Group"},"e8cd":{"name":"Speaker Notes"},"e92a":{"name":"Speaker Notes Off"},"e0d2":{"name":"Speaker Phone"},"e8ce":{"name":"Spellcheck"},"e838":{"name":"Star"},"e83a":{"name":"Star Border"},"e839":{"name":"Star Half"},"e8d0":{"name":"Stars"},"e0d3":{"name":"Stay Current Landscape"},"e0d4":{"name":"Stay Current Portrait"},"e0d5":{"name":"Stay Primary Landscape"},"e0d6":{"name":"Stay Primary Portrait"},"e047":{"name":"Stop"},"e0e3":{"name":"Stop Screen Share"},"e1db":{"name":"Storage"},"e8d1":{"name":"Store"},"e563":{"name":"Store Mall Directory"},"e41c":{"name":"Straighten"},"e56e":{"name":"Streetview"},"e257":{"name":"Strikethrough S"},"e41d":{"name":"Style"},"e5d9":{"name":"Subdirectory Arrow Left"},"e5da":{"name":"Subdirectory Arrow Right"},"e8d2":{"name":"Subject"},"e064":{"name":"Subscriptions"},"e048":{"name":"Subtitles"},"e56f":{"name":"Subway"},"e8d3":{"name":"Supervisor Account"},"e049":{"name":"Surround Sound"},"e0d7":{"name":"Swap Calls"},"e8d4":{"name":"Swap Horiz"},"e8d5":{"name":"Swap Vert"},"e8d6":{"name":"Swap Vertical Circle"},"e41e":{"name":"Switch Camera"},"e41f":{"name":"Switch Video"},"e627":{"name":"Sync"},"e628":{"name":"Sync Disabled"},"e629":{"name":"Sync Problem"},"e62a":{"name":"System Update"},"e8d7":{"name":"System Update Alt"},"e8d8":{"name":"Tab"},"e8d9":{"name":"Tab Unselected"},"e32f":{"name":"Tablet"},"e330":{"name":"Tablet Android"},"e331":{"name":"Tablet Mac"},"e420":{"name":"Tag Faces"},"e62b":{"name":"Tap And Play"},"e564":{"name":"Terrain"},"e262":{"name":"Text Fields"},"e165":{"name":"Text Format"},"e0d8":{"name":"Textsms"},"e421":{"name":"Texture"},"e8da":{"name":"Theaters"},"e8db":{"name":"Thumb Down"},"e8dc":{"name":"Thumb Up"},"e8dd":{"name":"Thumbs Up Down"},"e62c":{"name":"Time To Leave"},"e422":{"name":"Timelapse"},"e922":{"name":"Timeline"},"e425":{"name":"Timer"},"e423":{"name":"Timer 10"},"e424":{"name":"Timer 3"},"e426":{"name":"Timer Off"},"e264":{"name":"Title"},"e8de":{"name":"Toc"},"e8df":{"name":"Today"},"e8e0":{"name":"Toll"},"e427":{"name":"Tonality"},"e913":{"name":"Touch App"},"e332":{"name":"Toys"},"e8e1":{"name":"Track Changes"},"e565":{"name":"Traffic"},"e570":{"name":"Train"},"e571":{"name":"Tram"},"e572":{"name":"Transfer Within A Station"},"e428":{"name":"Transform"},"e8e2":{"name":"Translate"},"e8e3":{"name":"Trending Down"},"e8e4":{"name":"Trending Flat"},"e8e5":{"name":"Trending Up"},"e429":{"name":"Tune"},"e8e6":{"name":"Turned In"},"e8e7":{"name":"Turned In Not"},"e333":{"name":"Tv"},"e169":{"name":"Unarchive"},"e166":{"name":"Undo"},"e5d6":{"name":"Unfold Less"},"e5d7":{"name":"Unfold More"},"e923":{"name":"Update"},"e1e0":{"name":"Usb"},"e8e8":{"name":"Verified User"},"e258":{"name":"Vertical Align Bottom"},"e259":{"name":"Vertical Align Center"},"e25a":{"name":"Vertical Align Top"},"e62d":{"name":"Vibration"},"e070":{"name":"Video Call"},"e071":{"name":"Video Label"},"e04a":{"name":"Video Library"},"e04b":{"name":"Videocam"},"e04c":{"name":"Videocam Off"},"e338":{"name":"Videogame Asset"},"e8e9":{"name":"View Agenda"},"e8ea":{"name":"View Array"},"e8eb":{"name":"View Carousel"},"e8ec":{"name":"View Column"},"e42a":{"name":"View Comfy"},"e42b":{"name":"View Compact"},"e8ed":{"name":"View Day"},"e8ee":{"name":"View Headline"},"e8ef":{"name":"View List"},"e8f0":{"name":"View Module"},"e8f1":{"name":"View Quilt"},"e8f2":{"name":"View Stream"},"e8f3":{"name":"View Week"},"e435":{"name":"Vignette"},"e8f4":{"name":"Visibility"},"e8f5":{"name":"Visibility Off"},"e62e":{"name":"Voice Chat"},"e0d9":{"name":"Voicemail"},"e04d":{"name":"Volume Down"},"e04e":{"name":"Volume Mute"},"e04f":{"name":"Volume Off"},"e050":{"name":"Volume Up"},"e0da":{"name":"Vpn Key"},"e62f":{"name":"Vpn Lock"},"e1bc":{"name":"Wallpaper"},"e002":{"name":"Warning"},"e334":{"name":"Watch"},"e924":{"name":"Watch Later"},"e42c":{"name":"Wb Auto"},"e42d":{"name":"Wb Cloudy"},"e42e":{"name":"Wb Incandescent"},"e436":{"name":"Wb Iridescent"},"e430":{"name":"Wb Sunny"},"e63d":{"name":"Wc"},"e051":{"name":"Web"},"e069":{"name":"Web Asset"},"e16b":{"name":"Weekend"},"e80e":{"name":"Whatshot"},"e1bd":{"name":"Widgets"},"e63e":{"name":"Wifi"},"e1e1":{"name":"Wifi Lock"},"e1e2":{"name":"Wifi Tethering"},"e8f9":{"name":"Work"},"e25b":{"name":"Wrap Text"},"e8fa":{"name":"Youtube Searched For"},"e8ff":{"name":"Zoom In"},"e900":{"name":"Zoom Out"},"e56b":{"name":"Zoom Out Map"}}} \ No newline at end of file diff --git a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.svg b/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.svg deleted file mode 100644 index a449327e..00000000 --- a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.svg +++ /dev/null @@ -1,2373 +0,0 @@ - - - - - -Created by FontForge 20151118 at Mon Feb 8 11:58:02 2016 - By shyndman -Copyright 2015 Google, Inc. All Rights Reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.ttf b/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.ttf deleted file mode 100644 index 7015564a..00000000 Binary files a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.ttf and /dev/null differ diff --git a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.woff b/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.woff deleted file mode 100644 index b648a3ee..00000000 Binary files a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.woff and /dev/null differ diff --git a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.woff2 b/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.woff2 deleted file mode 100644 index 9fa21125..00000000 Binary files a/projects/wave-core/assets/fonts/material-design-icons/MaterialIcons-Regular.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/material-design-icons/README.md b/projects/wave-core/assets/fonts/material-design-icons/README.md deleted file mode 100644 index 39c1c014..00000000 --- a/projects/wave-core/assets/fonts/material-design-icons/README.md +++ /dev/null @@ -1,8 +0,0 @@ -The recommended way to use the Material Icons font is by linking to the web font hosted on Google Fonts: - -```html - -``` - -Read more in our full usage guide: -http://google.github.io/material-design-icons/#icon-font-for-the-web diff --git a/projects/wave-core/assets/fonts/material-design-icons/codepoints b/projects/wave-core/assets/fonts/material-design-icons/codepoints deleted file mode 100644 index 3c8b0750..00000000 --- a/projects/wave-core/assets/fonts/material-design-icons/codepoints +++ /dev/null @@ -1,932 +0,0 @@ -3d_rotation e84d -ac_unit eb3b -access_alarm e190 -access_alarms e191 -access_time e192 -accessibility e84e -accessible e914 -account_balance e84f -account_balance_wallet e850 -account_box e851 -account_circle e853 -adb e60e -add e145 -add_a_photo e439 -add_alarm e193 -add_alert e003 -add_box e146 -add_circle e147 -add_circle_outline e148 -add_location e567 -add_shopping_cart e854 -add_to_photos e39d -add_to_queue e05c -adjust e39e -airline_seat_flat e630 -airline_seat_flat_angled e631 -airline_seat_individual_suite e632 -airline_seat_legroom_extra e633 -airline_seat_legroom_normal e634 -airline_seat_legroom_reduced e635 -airline_seat_recline_extra e636 -airline_seat_recline_normal e637 -airplanemode_active e195 -airplanemode_inactive e194 -airplay e055 -airport_shuttle eb3c -alarm e855 -alarm_add e856 -alarm_off e857 -alarm_on e858 -album e019 -all_inclusive eb3d -all_out e90b -android e859 -announcement e85a -apps e5c3 -archive e149 -arrow_back e5c4 -arrow_downward e5db -arrow_drop_down e5c5 -arrow_drop_down_circle e5c6 -arrow_drop_up e5c7 -arrow_forward e5c8 -arrow_upward e5d8 -art_track e060 -aspect_ratio e85b -assessment e85c -assignment e85d -assignment_ind e85e -assignment_late e85f -assignment_return e860 -assignment_returned e861 -assignment_turned_in e862 -assistant e39f -assistant_photo e3a0 -attach_file e226 -attach_money e227 -attachment e2bc -audiotrack e3a1 -autorenew e863 -av_timer e01b -backspace e14a -backup e864 -battery_alert e19c -battery_charging_full e1a3 -battery_full e1a4 -battery_std e1a5 -battery_unknown e1a6 -beach_access eb3e -beenhere e52d -block e14b -bluetooth e1a7 -bluetooth_audio e60f -bluetooth_connected e1a8 -bluetooth_disabled e1a9 -bluetooth_searching e1aa -blur_circular e3a2 -blur_linear e3a3 -blur_off e3a4 -blur_on e3a5 -book e865 -bookmark e866 -bookmark_border e867 -border_all e228 -border_bottom e229 -border_clear e22a -border_color e22b -border_horizontal e22c -border_inner e22d -border_left e22e -border_outer e22f -border_right e230 -border_style e231 -border_top e232 -border_vertical e233 -branding_watermark e06b -brightness_1 e3a6 -brightness_2 e3a7 -brightness_3 e3a8 -brightness_4 e3a9 -brightness_5 e3aa -brightness_6 e3ab -brightness_7 e3ac -brightness_auto e1ab -brightness_high e1ac -brightness_low e1ad -brightness_medium e1ae -broken_image e3ad -brush e3ae -bubble_chart e6dd -bug_report e868 -build e869 -burst_mode e43c -business e0af -business_center eb3f -cached e86a -cake e7e9 -call e0b0 -call_end e0b1 -call_made e0b2 -call_merge e0b3 -call_missed e0b4 -call_missed_outgoing e0e4 -call_received e0b5 -call_split e0b6 -call_to_action e06c -camera e3af -camera_alt e3b0 -camera_enhance e8fc -camera_front e3b1 -camera_rear e3b2 -camera_roll e3b3 -cancel e5c9 -card_giftcard e8f6 -card_membership e8f7 -card_travel e8f8 -casino eb40 -cast e307 -cast_connected e308 -center_focus_strong e3b4 -center_focus_weak e3b5 -change_history e86b -chat e0b7 -chat_bubble e0ca -chat_bubble_outline e0cb -check e5ca -check_box e834 -check_box_outline_blank e835 -check_circle e86c -chevron_left e5cb -chevron_right e5cc -child_care eb41 -child_friendly eb42 -chrome_reader_mode e86d -class e86e -clear e14c -clear_all e0b8 -close e5cd -closed_caption e01c -cloud e2bd -cloud_circle e2be -cloud_done e2bf -cloud_download e2c0 -cloud_off e2c1 -cloud_queue e2c2 -cloud_upload e2c3 -code e86f -collections e3b6 -collections_bookmark e431 -color_lens e3b7 -colorize e3b8 -comment e0b9 -compare e3b9 -compare_arrows e915 -computer e30a -confirmation_number e638 -contact_mail e0d0 -contact_phone e0cf -contacts e0ba -content_copy e14d -content_cut e14e -content_paste e14f -control_point e3ba -control_point_duplicate e3bb -copyright e90c -create e150 -create_new_folder e2cc -credit_card e870 -crop e3be -crop_16_9 e3bc -crop_3_2 e3bd -crop_5_4 e3bf -crop_7_5 e3c0 -crop_din e3c1 -crop_free e3c2 -crop_landscape e3c3 -crop_original e3c4 -crop_portrait e3c5 -crop_rotate e437 -crop_square e3c6 -dashboard e871 -data_usage e1af -date_range e916 -dehaze e3c7 -delete e872 -delete_forever e92b -delete_sweep e16c -description e873 -desktop_mac e30b -desktop_windows e30c -details e3c8 -developer_board e30d -developer_mode e1b0 -device_hub e335 -devices e1b1 -devices_other e337 -dialer_sip e0bb -dialpad e0bc -directions e52e -directions_bike e52f -directions_boat e532 -directions_bus e530 -directions_car e531 -directions_railway e534 -directions_run e566 -directions_subway e533 -directions_transit e535 -directions_walk e536 -disc_full e610 -dns e875 -do_not_disturb e612 -do_not_disturb_alt e611 -do_not_disturb_off e643 -do_not_disturb_on e644 -dock e30e -domain e7ee -done e876 -done_all e877 -donut_large e917 -donut_small e918 -drafts e151 -drag_handle e25d -drive_eta e613 -dvr e1b2 -edit e3c9 -edit_location e568 -eject e8fb -email e0be -enhanced_encryption e63f -equalizer e01d -error e000 -error_outline e001 -euro_symbol e926 -ev_station e56d -event e878 -event_available e614 -event_busy e615 -event_note e616 -event_seat e903 -exit_to_app e879 -expand_less e5ce -expand_more e5cf -explicit e01e -explore e87a -exposure e3ca -exposure_neg_1 e3cb -exposure_neg_2 e3cc -exposure_plus_1 e3cd -exposure_plus_2 e3ce -exposure_zero e3cf -extension e87b -face e87c -fast_forward e01f -fast_rewind e020 -favorite e87d -favorite_border e87e -featured_play_list e06d -featured_video e06e -feedback e87f -fiber_dvr e05d -fiber_manual_record e061 -fiber_new e05e -fiber_pin e06a -fiber_smart_record e062 -file_download e2c4 -file_upload e2c6 -filter e3d3 -filter_1 e3d0 -filter_2 e3d1 -filter_3 e3d2 -filter_4 e3d4 -filter_5 e3d5 -filter_6 e3d6 -filter_7 e3d7 -filter_8 e3d8 -filter_9 e3d9 -filter_9_plus e3da -filter_b_and_w e3db -filter_center_focus e3dc -filter_drama e3dd -filter_frames e3de -filter_hdr e3df -filter_list e152 -filter_none e3e0 -filter_tilt_shift e3e2 -filter_vintage e3e3 -find_in_page e880 -find_replace e881 -fingerprint e90d -first_page e5dc -fitness_center eb43 -flag e153 -flare e3e4 -flash_auto e3e5 -flash_off e3e6 -flash_on e3e7 -flight e539 -flight_land e904 -flight_takeoff e905 -flip e3e8 -flip_to_back e882 -flip_to_front e883 -folder e2c7 -folder_open e2c8 -folder_shared e2c9 -folder_special e617 -font_download e167 -format_align_center e234 -format_align_justify e235 -format_align_left e236 -format_align_right e237 -format_bold e238 -format_clear e239 -format_color_fill e23a -format_color_reset e23b -format_color_text e23c -format_indent_decrease e23d -format_indent_increase e23e -format_italic e23f -format_line_spacing e240 -format_list_bulleted e241 -format_list_numbered e242 -format_paint e243 -format_quote e244 -format_shapes e25e -format_size e245 -format_strikethrough e246 -format_textdirection_l_to_r e247 -format_textdirection_r_to_l e248 -format_underlined e249 -forum e0bf -forward e154 -forward_10 e056 -forward_30 e057 -forward_5 e058 -free_breakfast eb44 -fullscreen e5d0 -fullscreen_exit e5d1 -functions e24a -g_translate e927 -gamepad e30f -games e021 -gavel e90e -gesture e155 -get_app e884 -gif e908 -golf_course eb45 -gps_fixed e1b3 -gps_not_fixed e1b4 -gps_off e1b5 -grade e885 -gradient e3e9 -grain e3ea -graphic_eq e1b8 -grid_off e3eb -grid_on e3ec -group e7ef -group_add e7f0 -group_work e886 -hd e052 -hdr_off e3ed -hdr_on e3ee -hdr_strong e3f1 -hdr_weak e3f2 -headset e310 -headset_mic e311 -healing e3f3 -hearing e023 -help e887 -help_outline e8fd -high_quality e024 -highlight e25f -highlight_off e888 -history e889 -home e88a -hot_tub eb46 -hotel e53a -hourglass_empty e88b -hourglass_full e88c -http e902 -https e88d -image e3f4 -image_aspect_ratio e3f5 -import_contacts e0e0 -import_export e0c3 -important_devices e912 -inbox e156 -indeterminate_check_box e909 -info e88e -info_outline e88f -input e890 -insert_chart e24b -insert_comment e24c -insert_drive_file e24d -insert_emoticon e24e -insert_invitation e24f -insert_link e250 -insert_photo e251 -invert_colors e891 -invert_colors_off e0c4 -iso e3f6 -keyboard e312 -keyboard_arrow_down e313 -keyboard_arrow_left e314 -keyboard_arrow_right e315 -keyboard_arrow_up e316 -keyboard_backspace e317 -keyboard_capslock e318 -keyboard_hide e31a -keyboard_return e31b -keyboard_tab e31c -keyboard_voice e31d -kitchen eb47 -label e892 -label_outline e893 -landscape e3f7 -language e894 -laptop e31e -laptop_chromebook e31f -laptop_mac e320 -laptop_windows e321 -last_page e5dd -launch e895 -layers e53b -layers_clear e53c -leak_add e3f8 -leak_remove e3f9 -lens e3fa -library_add e02e -library_books e02f -library_music e030 -lightbulb_outline e90f -line_style e919 -line_weight e91a -linear_scale e260 -link e157 -linked_camera e438 -list e896 -live_help e0c6 -live_tv e639 -local_activity e53f -local_airport e53d -local_atm e53e -local_bar e540 -local_cafe e541 -local_car_wash e542 -local_convenience_store e543 -local_dining e556 -local_drink e544 -local_florist e545 -local_gas_station e546 -local_grocery_store e547 -local_hospital e548 -local_hotel e549 -local_laundry_service e54a -local_library e54b -local_mall e54c -local_movies e54d -local_offer e54e -local_parking e54f -local_pharmacy e550 -local_phone e551 -local_pizza e552 -local_play e553 -local_post_office e554 -local_printshop e555 -local_see e557 -local_shipping e558 -local_taxi e559 -location_city e7f1 -location_disabled e1b6 -location_off e0c7 -location_on e0c8 -location_searching e1b7 -lock e897 -lock_open e898 -lock_outline e899 -looks e3fc -looks_3 e3fb -looks_4 e3fd -looks_5 e3fe -looks_6 e3ff -looks_one e400 -looks_two e401 -loop e028 -loupe e402 -low_priority e16d -loyalty e89a -mail e158 -mail_outline e0e1 -map e55b -markunread e159 -markunread_mailbox e89b -memory e322 -menu e5d2 -merge_type e252 -message e0c9 -mic e029 -mic_none e02a -mic_off e02b -mms e618 -mode_comment e253 -mode_edit e254 -monetization_on e263 -money_off e25c -monochrome_photos e403 -mood e7f2 -mood_bad e7f3 -more e619 -more_horiz e5d3 -more_vert e5d4 -motorcycle e91b -mouse e323 -move_to_inbox e168 -movie e02c -movie_creation e404 -movie_filter e43a -multiline_chart e6df -music_note e405 -music_video e063 -my_location e55c -nature e406 -nature_people e407 -navigate_before e408 -navigate_next e409 -navigation e55d -near_me e569 -network_cell e1b9 -network_check e640 -network_locked e61a -network_wifi e1ba -new_releases e031 -next_week e16a -nfc e1bb -no_encryption e641 -no_sim e0cc -not_interested e033 -note e06f -note_add e89c -notifications e7f4 -notifications_active e7f7 -notifications_none e7f5 -notifications_off e7f6 -notifications_paused e7f8 -offline_pin e90a -ondemand_video e63a -opacity e91c -open_in_browser e89d -open_in_new e89e -open_with e89f -pages e7f9 -pageview e8a0 -palette e40a -pan_tool e925 -panorama e40b -panorama_fish_eye e40c -panorama_horizontal e40d -panorama_vertical e40e -panorama_wide_angle e40f -party_mode e7fa -pause e034 -pause_circle_filled e035 -pause_circle_outline e036 -payment e8a1 -people e7fb -people_outline e7fc -perm_camera_mic e8a2 -perm_contact_calendar e8a3 -perm_data_setting e8a4 -perm_device_information e8a5 -perm_identity e8a6 -perm_media e8a7 -perm_phone_msg e8a8 -perm_scan_wifi e8a9 -person e7fd -person_add e7fe -person_outline e7ff -person_pin e55a -person_pin_circle e56a -personal_video e63b -pets e91d -phone e0cd -phone_android e324 -phone_bluetooth_speaker e61b -phone_forwarded e61c -phone_in_talk e61d -phone_iphone e325 -phone_locked e61e -phone_missed e61f -phone_paused e620 -phonelink e326 -phonelink_erase e0db -phonelink_lock e0dc -phonelink_off e327 -phonelink_ring e0dd -phonelink_setup e0de -photo e410 -photo_album e411 -photo_camera e412 -photo_filter e43b -photo_library e413 -photo_size_select_actual e432 -photo_size_select_large e433 -photo_size_select_small e434 -picture_as_pdf e415 -picture_in_picture e8aa -picture_in_picture_alt e911 -pie_chart e6c4 -pie_chart_outlined e6c5 -pin_drop e55e -place e55f -play_arrow e037 -play_circle_filled e038 -play_circle_outline e039 -play_for_work e906 -playlist_add e03b -playlist_add_check e065 -playlist_play e05f -plus_one e800 -poll e801 -polymer e8ab -pool eb48 -portable_wifi_off e0ce -portrait e416 -power e63c -power_input e336 -power_settings_new e8ac -pregnant_woman e91e -present_to_all e0df -print e8ad -priority_high e645 -public e80b -publish e255 -query_builder e8ae -question_answer e8af -queue e03c -queue_music e03d -queue_play_next e066 -radio e03e -radio_button_checked e837 -radio_button_unchecked e836 -rate_review e560 -receipt e8b0 -recent_actors e03f -record_voice_over e91f -redeem e8b1 -redo e15a -refresh e5d5 -remove e15b -remove_circle e15c -remove_circle_outline e15d -remove_from_queue e067 -remove_red_eye e417 -remove_shopping_cart e928 -reorder e8fe -repeat e040 -repeat_one e041 -replay e042 -replay_10 e059 -replay_30 e05a -replay_5 e05b -reply e15e -reply_all e15f -report e160 -report_problem e8b2 -restaurant e56c -restaurant_menu e561 -restore e8b3 -restore_page e929 -ring_volume e0d1 -room e8b4 -room_service eb49 -rotate_90_degrees_ccw e418 -rotate_left e419 -rotate_right e41a -rounded_corner e920 -router e328 -rowing e921 -rss_feed e0e5 -rv_hookup e642 -satellite e562 -save e161 -scanner e329 -schedule e8b5 -school e80c -screen_lock_landscape e1be -screen_lock_portrait e1bf -screen_lock_rotation e1c0 -screen_rotation e1c1 -screen_share e0e2 -sd_card e623 -sd_storage e1c2 -search e8b6 -security e32a -select_all e162 -send e163 -sentiment_dissatisfied e811 -sentiment_neutral e812 -sentiment_satisfied e813 -sentiment_very_dissatisfied e814 -sentiment_very_satisfied e815 -settings e8b8 -settings_applications e8b9 -settings_backup_restore e8ba -settings_bluetooth e8bb -settings_brightness e8bd -settings_cell e8bc -settings_ethernet e8be -settings_input_antenna e8bf -settings_input_component e8c0 -settings_input_composite e8c1 -settings_input_hdmi e8c2 -settings_input_svideo e8c3 -settings_overscan e8c4 -settings_phone e8c5 -settings_power e8c6 -settings_remote e8c7 -settings_system_daydream e1c3 -settings_voice e8c8 -share e80d -shop e8c9 -shop_two e8ca -shopping_basket e8cb -shopping_cart e8cc -short_text e261 -show_chart e6e1 -shuffle e043 -signal_cellular_4_bar e1c8 -signal_cellular_connected_no_internet_4_bar e1cd -signal_cellular_no_sim e1ce -signal_cellular_null e1cf -signal_cellular_off e1d0 -signal_wifi_4_bar e1d8 -signal_wifi_4_bar_lock e1d9 -signal_wifi_off e1da -sim_card e32b -sim_card_alert e624 -skip_next e044 -skip_previous e045 -slideshow e41b -slow_motion_video e068 -smartphone e32c -smoke_free eb4a -smoking_rooms eb4b -sms e625 -sms_failed e626 -snooze e046 -sort e164 -sort_by_alpha e053 -spa eb4c -space_bar e256 -speaker e32d -speaker_group e32e -speaker_notes e8cd -speaker_notes_off e92a -speaker_phone e0d2 -spellcheck e8ce -star e838 -star_border e83a -star_half e839 -stars e8d0 -stay_current_landscape e0d3 -stay_current_portrait e0d4 -stay_primary_landscape e0d5 -stay_primary_portrait e0d6 -stop e047 -stop_screen_share e0e3 -storage e1db -store e8d1 -store_mall_directory e563 -straighten e41c -streetview e56e -strikethrough_s e257 -style e41d -subdirectory_arrow_left e5d9 -subdirectory_arrow_right e5da -subject e8d2 -subscriptions e064 -subtitles e048 -subway e56f -supervisor_account e8d3 -surround_sound e049 -swap_calls e0d7 -swap_horiz e8d4 -swap_vert e8d5 -swap_vertical_circle e8d6 -switch_camera e41e -switch_video e41f -sync e627 -sync_disabled e628 -sync_problem e629 -system_update e62a -system_update_alt e8d7 -tab e8d8 -tab_unselected e8d9 -tablet e32f -tablet_android e330 -tablet_mac e331 -tag_faces e420 -tap_and_play e62b -terrain e564 -text_fields e262 -text_format e165 -textsms e0d8 -texture e421 -theaters e8da -thumb_down e8db -thumb_up e8dc -thumbs_up_down e8dd -time_to_leave e62c -timelapse e422 -timeline e922 -timer e425 -timer_10 e423 -timer_3 e424 -timer_off e426 -title e264 -toc e8de -today e8df -toll e8e0 -tonality e427 -touch_app e913 -toys e332 -track_changes e8e1 -traffic e565 -train e570 -tram e571 -transfer_within_a_station e572 -transform e428 -translate e8e2 -trending_down e8e3 -trending_flat e8e4 -trending_up e8e5 -tune e429 -turned_in e8e6 -turned_in_not e8e7 -tv e333 -unarchive e169 -undo e166 -unfold_less e5d6 -unfold_more e5d7 -update e923 -usb e1e0 -verified_user e8e8 -vertical_align_bottom e258 -vertical_align_center e259 -vertical_align_top e25a -vibration e62d -video_call e070 -video_label e071 -video_library e04a -videocam e04b -videocam_off e04c -videogame_asset e338 -view_agenda e8e9 -view_array e8ea -view_carousel e8eb -view_column e8ec -view_comfy e42a -view_compact e42b -view_day e8ed -view_headline e8ee -view_list e8ef -view_module e8f0 -view_quilt e8f1 -view_stream e8f2 -view_week e8f3 -vignette e435 -visibility e8f4 -visibility_off e8f5 -voice_chat e62e -voicemail e0d9 -volume_down e04d -volume_mute e04e -volume_off e04f -volume_up e050 -vpn_key e0da -vpn_lock e62f -wallpaper e1bc -warning e002 -watch e334 -watch_later e924 -wb_auto e42c -wb_cloudy e42d -wb_incandescent e42e -wb_iridescent e436 -wb_sunny e430 -wc e63d -web e051 -web_asset e069 -weekend e16b -whatshot e80e -widgets e1bd -wifi e63e -wifi_lock e1e1 -wifi_tethering e1e2 -work e8f9 -wrap_text e25b -youtube_searched_for e8fa -zoom_in e8ff -zoom_out e900 -zoom_out_map e56b diff --git a/projects/wave-core/assets/fonts/material-design-icons/material-icons.css b/projects/wave-core/assets/fonts/material-design-icons/material-icons.css deleted file mode 100644 index c183a6e0..00000000 --- a/projects/wave-core/assets/fonts/material-design-icons/material-icons.css +++ /dev/null @@ -1,33 +0,0 @@ -@font-face { - font-family: 'Material Icons'; - font-style: normal; - font-weight: 400; - src: url(MaterialIcons-Regular.eot); /* For IE6-8 */ - src: local('Material Icons'), local('MaterialIcons-Regular'), url(MaterialIcons-Regular.woff2) format('woff2'), - url(MaterialIcons-Regular.woff) format('woff'), url(MaterialIcons-Regular.ttf) format('truetype'); -} - -.material-icons { - font-family: 'Material Icons'; - font-weight: normal; - font-style: normal; - font-size: 24px; /* Preferred icon size */ - display: inline-block; - line-height: 1; - text-transform: none; - letter-spacing: normal; - word-wrap: normal; - white-space: nowrap; - direction: ltr; - - /* Support for all WebKit browsers. */ - -webkit-font-smoothing: antialiased; - /* Support for Safari and Chrome. */ - text-rendering: optimizeLegibility; - - /* Support for Firefox. */ - -moz-osx-font-smoothing: grayscale; - - /* Support for IE. */ - font-feature-settings: 'liga'; -} diff --git a/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6D6MmTpA.woff2 b/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6D6MmTpA.woff2 deleted file mode 100644 index fdba9969..00000000 Binary files a/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6D6MmTpA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6H6Mk.woff2 b/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6H6Mk.woff2 deleted file mode 100644 index ffb22897..00000000 Binary files a/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6H6Mk.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6I6MmTpA.woff2 b/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6I6MmTpA.woff2 deleted file mode 100644 index b43fba2f..00000000 Binary files a/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6I6MmTpA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6J6MmTpA.woff2 b/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6J6MmTpA.woff2 deleted file mode 100644 index c07389dc..00000000 Binary files a/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6J6MmTpA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6K6MmTpA.woff2 b/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6K6MmTpA.woff2 deleted file mode 100644 index 55a4de4c..00000000 Binary files a/projects/wave-core/assets/fonts/pacifico/FwZY7-Qmy14u9lezJ-6K6MmTpA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/pacifico/pacifico.css b/projects/wave-core/assets/fonts/pacifico/pacifico.css deleted file mode 100644 index 120374dc..00000000 --- a/projects/wave-core/assets/fonts/pacifico/pacifico.css +++ /dev/null @@ -1,41 +0,0 @@ -/* cyrillic-ext */ -@font-face { - font-family: 'Pacifico'; - font-style: normal; - font-weight: 400; - src: local('Pacifico Regular'), local('Pacifico-Regular'), url(FwZY7-Qmy14u9lezJ-6K6MmTpA.woff2) format('woff2'); - unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; -} -/* cyrillic */ -@font-face { - font-family: 'Pacifico'; - font-style: normal; - font-weight: 400; - src: local('Pacifico Regular'), local('Pacifico-Regular'), url(FwZY7-Qmy14u9lezJ-6D6MmTpA.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* vietnamese */ -@font-face { - font-family: 'Pacifico'; - font-style: normal; - font-weight: 400; - src: local('Pacifico Regular'), local('Pacifico-Regular'), url(FwZY7-Qmy14u9lezJ-6I6MmTpA.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Pacifico'; - font-style: normal; - font-weight: 400; - src: local('Pacifico Regular'), local('Pacifico-Regular'), url(FwZY7-Qmy14u9lezJ-6J6MmTpA.woff2) format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Pacifico'; - font-style: normal; - font-weight: 400; - src: local('Pacifico Regular'), local('Pacifico-Regular'), url(FwZY7-Qmy14u9lezJ-6H6Mk.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, - U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} diff --git a/projects/wave-core/assets/fonts/roboto/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2 b/projects/wave-core/assets/fonts/roboto/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2 deleted file mode 100644 index ed0b13ca..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/-L14Jk06m6pUHB-5mXQQnRJtnKITppOI_IvcXXDNrsc.woff2 b/projects/wave-core/assets/fonts/roboto/-L14Jk06m6pUHB-5mXQQnRJtnKITppOI_IvcXXDNrsc.woff2 deleted file mode 100644 index 6cb7a2d0..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/-L14Jk06m6pUHB-5mXQQnRJtnKITppOI_IvcXXDNrsc.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/0eC6fl06luXEYWpBSJvXCBJtnKITppOI_IvcXXDNrsc.woff2 b/projects/wave-core/assets/fonts/roboto/0eC6fl06luXEYWpBSJvXCBJtnKITppOI_IvcXXDNrsc.woff2 deleted file mode 100644 index 45bd7093..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/0eC6fl06luXEYWpBSJvXCBJtnKITppOI_IvcXXDNrsc.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/CWB0XYA8bzo0kSThX0UTuA.woff2 b/projects/wave-core/assets/fonts/roboto/CWB0XYA8bzo0kSThX0UTuA.woff2 deleted file mode 100644 index 120796bb..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/CWB0XYA8bzo0kSThX0UTuA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2 b/projects/wave-core/assets/fonts/roboto/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2 deleted file mode 100644 index 0c7aec28..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/Fl4y0QdOxyyTHEGMXX8kcRJtnKITppOI_IvcXXDNrsc.woff2 b/projects/wave-core/assets/fonts/roboto/Fl4y0QdOxyyTHEGMXX8kcRJtnKITppOI_IvcXXDNrsc.woff2 deleted file mode 100644 index 137a9771..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/Fl4y0QdOxyyTHEGMXX8kcRJtnKITppOI_IvcXXDNrsc.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/Hgo13k-tfSpn0qi1SFdUfVtXRa8TVwTICgirnJhmVJw.woff2 b/projects/wave-core/assets/fonts/roboto/Hgo13k-tfSpn0qi1SFdUfVtXRa8TVwTICgirnJhmVJw.woff2 deleted file mode 100644 index c34c1280..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/Hgo13k-tfSpn0qi1SFdUfVtXRa8TVwTICgirnJhmVJw.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/I3S1wsgSg9YCurV6PUkTORJtnKITppOI_IvcXXDNrsc.woff2 b/projects/wave-core/assets/fonts/roboto/I3S1wsgSg9YCurV6PUkTORJtnKITppOI_IvcXXDNrsc.woff2 deleted file mode 100644 index 6e5a590b..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/I3S1wsgSg9YCurV6PUkTORJtnKITppOI_IvcXXDNrsc.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/NYDWBdD4gIq26G5XYbHsFBJtnKITppOI_IvcXXDNrsc.woff2 b/projects/wave-core/assets/fonts/roboto/NYDWBdD4gIq26G5XYbHsFBJtnKITppOI_IvcXXDNrsc.woff2 deleted file mode 100644 index a940e021..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/NYDWBdD4gIq26G5XYbHsFBJtnKITppOI_IvcXXDNrsc.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2 b/projects/wave-core/assets/fonts/roboto/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2 deleted file mode 100644 index 7936b665..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/Pru33qjShpZSmG3z6VYwnRJtnKITppOI_IvcXXDNrsc.woff2 b/projects/wave-core/assets/fonts/roboto/Pru33qjShpZSmG3z6VYwnRJtnKITppOI_IvcXXDNrsc.woff2 deleted file mode 100644 index 8acbd411..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/Pru33qjShpZSmG3z6VYwnRJtnKITppOI_IvcXXDNrsc.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2 b/projects/wave-core/assets/fonts/roboto/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2 deleted file mode 100644 index e4546e49..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2 b/projects/wave-core/assets/fonts/roboto/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2 deleted file mode 100644 index d08397f7..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/fonts/roboto/roboto.css b/projects/wave-core/assets/fonts/roboto/roboto.css deleted file mode 100644 index b1b63637..00000000 --- a/projects/wave-core/assets/fonts/roboto/roboto.css +++ /dev/null @@ -1,114 +0,0 @@ -/* cyrillic-ext */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(0eC6fl06luXEYWpBSJvXCBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; -} -/* cyrillic */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(Fl4y0QdOxyyTHEGMXX8kcRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek-ext */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(-L14Jk06m6pUHB-5mXQQnRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; -} -/* greek */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(I3S1wsgSg9YCurV6PUkTORJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(NYDWBdD4gIq26G5XYbHsFBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(Pru33qjShpZSmG3z6VYwnRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(Hgo13k-tfSpn0qi1SFdUfVtXRa8TVwTICgirnJhmVJw.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, - U+F000; -} -/* cyrillic-ext */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; -} -/* cyrillic */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek-ext */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; -} -/* greek */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(CWB0XYA8bzo0kSThX0UTuA.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, - U+F000; -} diff --git a/projects/wave-core/assets/fonts/roboto/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2 b/projects/wave-core/assets/fonts/roboto/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2 deleted file mode 100644 index f630772d..00000000 Binary files a/projects/wave-core/assets/fonts/roboto/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2 and /dev/null differ diff --git a/projects/wave-core/assets/gbif-default-fields.json b/projects/wave-core/assets/gbif-default-fields.json deleted file mode 100644 index e40dff87..00000000 --- a/projects/wave-core/assets/gbif-default-fields.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name": "gbifid", - "datatype": "Int32" - }, - { - "name": "basisofrecord", - "datatype": "Alphanumeric" - }, - { - "name": "scientificname", - "datatype": "Alphanumeric" - } -] diff --git a/projects/wave-core/assets/geobon-logo.svg b/projects/wave-core/assets/geobon-logo.svg deleted file mode 100644 index 03e10243..00000000 --- a/projects/wave-core/assets/geobon-logo.svg +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/wave-core/assets/icons/cogs.svg b/projects/wave-core/assets/icons/cogs.svg deleted file mode 100644 index db93d9b7..00000000 --- a/projects/wave-core/assets/icons/cogs.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/projects/wave-core/assets/icons/grid4_24.svg b/projects/wave-core/assets/icons/grid4_24.svg deleted file mode 100644 index 2864703c..00000000 --- a/projects/wave-core/assets/icons/grid4_24.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/projects/wave-core/assets/icons/grid5_24.svg b/projects/wave-core/assets/icons/grid5_24.svg deleted file mode 100644 index b2bc0f73..00000000 --- a/projects/wave-core/assets/icons/grid5_24.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/wave-core/assets/icons/line_24.svg b/projects/wave-core/assets/icons/line_24.svg deleted file mode 100644 index 1af01def..00000000 --- a/projects/wave-core/assets/icons/line_24.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/projects/wave-core/assets/icons/point_24.svg b/projects/wave-core/assets/icons/point_24.svg deleted file mode 100644 index 444f0f8a..00000000 --- a/projects/wave-core/assets/icons/point_24.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/projects/wave-core/assets/icons/polygon_24.svg b/projects/wave-core/assets/icons/polygon_24.svg deleted file mode 100644 index bad514e8..00000000 --- a/projects/wave-core/assets/icons/polygon_24.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/projects/wave-core/assets/images/lineage.png b/projects/wave-core/assets/images/lineage.png deleted file mode 100644 index 4e5e1138..00000000 Binary files a/projects/wave-core/assets/images/lineage.png and /dev/null differ diff --git a/projects/wave-core/assets/images/logo-senckenberg.png b/projects/wave-core/assets/images/logo-senckenberg.png deleted file mode 100644 index fcf81532..00000000 Binary files a/projects/wave-core/assets/images/logo-senckenberg.png and /dev/null differ diff --git a/projects/wave-core/assets/images/logo_agdbs.png b/projects/wave-core/assets/images/logo_agdbs.png deleted file mode 100644 index 5490e4e3..00000000 Binary files a/projects/wave-core/assets/images/logo_agdbs.png and /dev/null differ diff --git a/projects/wave-core/assets/images/logo_umr.png b/projects/wave-core/assets/images/logo_umr.png deleted file mode 100644 index a4b3111a..00000000 Binary files a/projects/wave-core/assets/images/logo_umr.png and /dev/null differ diff --git a/projects/wave-core/assets/images/overview.png b/projects/wave-core/assets/images/overview.png deleted file mode 100644 index c9f56692..00000000 Binary files a/projects/wave-core/assets/images/overview.png and /dev/null differ diff --git a/projects/wave-core/assets/mapping-data-sources.json b/projects/wave-core/assets/mapping-data-sources.json deleted file mode 100644 index 81c590a6..00000000 --- a/projects/wave-core/assets/mapping-data-sources.json +++ /dev/null @@ -1,913 +0,0 @@ -{ - "sourcelist": { - "isric_wise": { - "name": "ISRIC-WISE", - "channels": [ - { - "name": "bsat", - "datatype": "Float64", - "max": 100, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "bulk", - "datatype": "Float64", - "max": 2, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "cecc", - "datatype": "Float64", - "max": 115, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "cecs", - "datatype": "Float64", - "max": 103, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "cfrag", - "datatype": "Float64", - "max": 37, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "clpc", - "datatype": "Float64", - "max": 54, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "cnrt", - "datatype": "Float64", - "max": 29, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "ecec", - "datatype": "Float64", - "max": 51, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "elco", - "datatype": "Float64", - "max": 32, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "gyps", - "datatype": "Float64", - "max": 200, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "phaq", - "datatype": "Float64", - "max": 9, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "prop", - "datatype": "Float64", - "max": 100, - "min": 24, - "nodata": -1.7976931348623e308 - }, - { - "name": "sdto", - "datatype": "Float64", - "max": 98, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "tawc", - "datatype": "Float64", - "max": 38, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "tceq", - "datatype": "Float64", - "max": 212, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "totc", - "datatype": "Float64", - "max": 408, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "totn", - "datatype": "Float64", - "max": 26, - "min": -7, - "nodata": -1.7976931348623e308 - }, - { - "name": "stpc", - "datatype": "Float64", - "max": 51, - "min": -7, - "nodata": -1.7976931348623e308 - } - ], - "coords": { - "epsg": 4326, - "origin": [-179.99999999952, 83.583332774984], - "scale": [0.083333333, -0.083333333], - "size": [4319, 1675] - } - }, - "worldclim": { - "name": "WorldClim", - "channels": [ - { - "name": "Min Temp", - "colorizer": "temperature", - "datatype": "Int16", - "max": 1000, - "min": -1000, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Max Temp", - "colorizer": "temperature", - "datatype": "Int16", - "max": 1000, - "min": -1000, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Avg Temp", - "colorizer": "temperature", - "datatype": "Int16", - "max": 1000, - "min": -1000, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Precipitation", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Altitude", - "colorizer": "height", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 1 (annual mean temperature)", - "colorizer": "temperature", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Bio 2 (mean diurnal range)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 3 (isothermality)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 4 (temp seasonality)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 5 (max temp of warmest month)", - "colorizer": "temperature", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Bio 6 (min temp of coldest month)", - "colorizer": "temperature", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Bio 7 (temp annual range)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 8 (mean temp of wettest quarter)", - "colorizer": "temperature", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Bio 9 (mean temp of dryest quarter)", - "colorizer": "temperature", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Bio 10 (mean temp of warmest quarter)", - "colorizer": "temperature", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Bio 11 (mean temp of coldest quarter)", - "colorizer": "temperature", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Bio 12 (annual precipitation)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 13 (prec of wettest month)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 14 (prec of driest month)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 15 (prec seasonality)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 16 (prec of wettest quarter)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 17 (prec of driest quarter)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 18 (prec of warmest quarter)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Bio 19 (prec of coldest quarter)", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - } - ], - "coords": { - "epsg": 4326, - "origin": [-180, 90], - "scale": [0.0083333333333333, -0.0083333333333333], - "size": [43200, 18000] - } - }, - "msg9_geos": { - "name": "Meteosat 2nd Generation", - "colorizer": "grey", - "channels": [ - { - "datatype": "Int16", - "nodata": 0, - "name": "VIS 0.6", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - }, - { - "datatype": "Int16", - "nodata": 0, - "name": "VIS 0.8", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - }, - { - "datatype": "Int16", - "nodata": 0, - "name": "NIR 1.6", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - }, - { - "datatype": "Int16", - "nodata": 0, - "name": "IR 3.9", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - }, - { - "datatype": "Int16", - "nodata": 0, - "name": "WV 6.2", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - }, - { - "datatype": "Int16", - "nodata": 0, - "name": "WV 7.3", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - }, - { - "datatype": "Int16", - "nodata": 0, - "name": "IR 8.7", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - }, - { - "datatype": "Int16", - "nodata": 0, - "name": "IR 9.7", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - }, - { - "datatype": "Int16", - "nodata": 0, - "name": "IR 10.8", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - }, - { - "datatype": "Int16", - "nodata": 0, - "name": "IR 12.0", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - }, - { - "datatype": "Int16", - "nodata": 0, - "name": "IR 13.4", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - } - ], - "coords": { - "epsg": 40453, - "origin": [-5570248.4773393, 5570248.4773393], - "scale": [3000.4031658173, -3000.4031658173], - "size": [3712, 3712] - } - }, - "srtm": { - "name": "SRTM elevation model", - "colorizer": "height", - "channels": [ - { - "name": "Elevation", - "datatype": "Int16", - "nodata": -32768, - "unit": { - "measurement": "elevation", - "unit": "m" - } - } - ], - "coords": { - "epsg": 4326, - "origin": [-180, 60], - "scale": [0.00083333333333334, -0.00083333333333334], - "size": [432000, 144000] - } - }, - "glc2000_global": { - "name": "Global Land Cover Map for the Year 2000", - "colorizer": "glc", - "channels": [ - { - "datatype": "Byte", - "nodata": 0, - "unit": { - "measurement": "land usage", - "unit": "classification", - "classes": { - "1": "Tree Cover, broadleaved, evergreen", - "2": "Tree Cover, broadleaved, deciduous, closed", - "3": "Tree Cover, broadleaved, deciduous, open", - "4": "Tree Cover, needle-leaved, evergreen", - "5": "Tree Cover, needle-leaved, deciduous", - "6": "Tree Cover, mixed leaf type", - "7": "Tree Cover, regularly flooded, fresh water", - "8": "Tree Cover, regularly flooded, saline water", - "9": "Mosaic: Tree Cover / Other natural vegetation", - "10": "Tree Cover, burnt", - "11": "Shrub Cover, closed-open, evergreen", - "12": "Shrub Cover, closed-open, deciduous", - "13": "Herbaceous Cover, closed-open", - "14": "Sparse Herbaceous or sparse Shrub Cover", - "15": "Regularly flooded Shrub and/or Herbaceous Cover", - "16": "Cultivated and managed areas", - "17": "Mosaic: Cropland / Tree Cover / Other natural vegetation", - "18": "Mosaic: Cropland / Shrub or Grass Cover", - "19": "Bare Areas", - "20": "Water Bodies", - "21": "Snow and Ice", - "22": "Artificial surfaced and associated areas" - } - } - } - ], - "coords": { - "epsg": 4326, - "origin": [-180, 90], - "scale": [0.0089285714, -0.0089285714], - "size": [40320, 16353] - } - }, - "cruts": { - "name": "CRU Time Series", - "colorizer": "grey", - "channels": [ - { - "datatype": "Float64", - "max": 100, - "min": -100, - "nodata": 9.9692099683869e36, - "name": "Mean temperature (tmp)", - "colorizer": "temperature" - }, - { - "datatype": "Float64", - "max": 100, - "min": -100, - "nodata": 9.9692099683869e36, - "name": "Min temperature (tmn)", - "colorizer": "temperature" - }, - { - "datatype": "Float64", - "max": 100, - "min": -100, - "nodata": 9.9692099683869e36, - "name": "Max temperature (tmx)", - "colorizer": "temperature" - }, - { - "datatype": "Float64", - "max": 100, - "min": -100, - "nodata": 9.9692099683869e36, - "name": "Diurnal temperature range (dtr)" - }, - { - "datatype": "Float64", - "max": 100, - "min": -100, - "nodata": 9.9692099683869e36, - "name": "cloud cover (cld)" - }, - { - "datatype": "Float64", - "max": 100, - "min": -100, - "nodata": 9.9692099683869e36, - "name": "Potential evopotranspiration (pet)" - }, - { - "datatype": "Float64", - "max": 100, - "min": -100, - "nodata": 9.9692099683869e36, - "name": "Precipitation total (pre)" - }, - { - "datatype": "Float64", - "max": 100, - "min": -100, - "nodata": 9.9692099683869e36, - "name": "Vapor Pressure (vap)" - }, - { - "datatype": "Float64", - "max": 31, - "min": 0, - "nodata": 9.9692099683869e36, - "name": "Rainday counts (wet)" - }, - { - "datatype": "Float64", - "max": 31, - "min": 0, - "nodata": 9.9692099683869e36, - "name": "Frostdays counts (frs)" - } - ], - "coords": { - "epsg": 4326, - "origin": [-180, 90], - "scale": [0.5, -0.5], - "size": [720, 360] - } - }, - "msg9_geos_hrv": { - "name": "Meteosat 2nd Generation HRV", - "colorizer": "grey", - "channels": [ - { - "datatype": "Int16", - "nodata": 0, - "name": "HRV", - "unit": { - "measurement": "raw", - "unit": "unknown", - "interpolation": "continuous", - "min": 0, - "max": 1023 - }, - "transform": { - "datatype": "Float32", - "offset": "msg.CalibrationOffset", - "scale": "msg.CalibrationSlope", - "unit": { - "measurement": "radiance", - "unit": "W\u00b7m^(-2)\u00b7sr^(-1)\u00b7cm^(-1)", - "interpolation": "continuous" - } - } - } - ], - "coords": { - "epsg": 40453, - "origin": [-5571248.3903748, 5571248.3903748], - "scale": [1000.1343488693, -1000.1343488693], - "size": [11136, 11136] - } - }, - "modis_vcf": { - "name": "MODIS Vegetation Continuous Fields", - "colorizer": "gray", - "channels": [ - { - "name": "TRE", - "datatype": "Byte", - "max": 100, - "min": 0, - "nodata": 200 - } - ], - "coords": { - "epsg": 4326, - "origin": [-180, 84], - "scale": [0.002083333333333, -0.002083333333333], - "size": [172800, 71040] - } - }, - "btw2015_paper_demo": { - "name": "BTW Paper Demo Data", - "channels": [ - { - "name": "Worldclim Precipitation December", - "datatype": "Int16", - "max": 310, - "min": 0, - "nodata": -9999 - }, - { - "name": "Worldclim Precipitation January", - "datatype": "Int16", - "max": 310, - "min": 0, - "nodata": -9999 - }, - { - "name": "Mean Temperature December", - "colorizer": "temperature", - "datatype": "Int16", - "max": 300, - "min": -400, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Mean Temperature January", - "colorizer": "temperature", - "datatype": "Int16", - "max": 300, - "min": -400, - "nodata": -9999, - "transform": { - "datatype": "Float32", - "offset": 0, - "scale": 0.1 - } - }, - { - "name": "Worldclim Altitude", - "colorizer": "height", - "datatype": "Int16", - "max": 1500, - "min": -0, - "nodata": -9999 - }, - { - "name": "Global Land Cover 2000", - "colorizer": "glc", - "datatype": "Byte", - "max": 23, - "min": 1, - "nodata": 0 - }, - { - "name": "Result of the workflow", - "colorizer": "grey", - "datatype": "Byte", - "min": 0, - "max": 2, - "nodata": 2 - } - ], - "coords": { - "epsg": 4326, - "origin": [-179.004, 85.0045], - "scale": [0.00833333, -0.00833333], - "size": [42960, 16800] - } - } - } -} diff --git a/projects/wave-core/assets/operator-type-icons/expression.png b/projects/wave-core/assets/operator-type-icons/expression.png deleted file mode 100644 index 5d32eb61..00000000 Binary files a/projects/wave-core/assets/operator-type-icons/expression.png and /dev/null differ diff --git a/projects/wave-core/assets/vat_logo.svg b/projects/wave-core/assets/vat_logo.svg deleted file mode 100644 index 9822824a..00000000 --- a/projects/wave-core/assets/vat_logo.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/projects/wave-core/karma.conf.js b/projects/wave-core/karma.conf.js deleted file mode 100644 index 2dc5bb88..00000000 --- a/projects/wave-core/karma.conf.js +++ /dev/null @@ -1,32 +0,0 @@ -// Karma configuration file, see link for more information -// https://karma-runner.github.io/1.0/config/configuration-file.html - -module.exports = function (config) { - config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], - plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage-istanbul-reporter'), - require('@angular-devkit/build-angular/plugins/karma'), - ], - client: { - clearContext: false, // leave Jasmine Spec Runner output visible in browser - }, - coverageIstanbulReporter: { - dir: require('path').join(__dirname, '../../coverage/wave-core'), - reports: ['html', 'lcovonly', 'text-summary'], - fixWebpackSourcePaths: true, - }, - reporters: ['progress', 'kjhtml'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome'], - singleRun: false, - restartOnFileChange: true, - }); -}; diff --git a/projects/wave-core/ng-package.json b/projects/wave-core/ng-package.json deleted file mode 100644 index 5533c0f3..00000000 --- a/projects/wave-core/ng-package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", - "dest": "../../dist/wave-core", - "lib": { - "entryFile": "src/public-api.ts", - "umdModuleIds": { - "codemirror": "codemirror", - "d3": "d3", - "dagre-d3": "dagreD3", - "immutable": "immutable", - "moment": "moment", - "ngx-color-picker": "ngxColorPicker", - "ol/Collection": "OlCollection", - "ol/Map": "OlMap", - "ol/View": "OlView", - "ol/extent": "extent", - "ol/format": "format", - "ol/format/GeoJSON": "OlFormatGeoJSON", - "ol/geom/GeometryType": "OlGeometryType", - "ol/geom/Point": "OlGeomPoint", - "ol/interaction/Draw": "OlInteractionDraw", - "ol/interaction/Select": "OlInteractionSelect", - "ol/layer": "layer", - "ol/layer/Image": "OlLayerImage", - "ol/layer/Tile": "OlLayerTile", - "ol/layer/Vector": "OlLayerVector", - "ol/proj": "proj", - "ol/proj/proj4": "olproj4", - "ol/source": "source", - "ol/source/ImageStatic": "OlImageStatic", - "ol/source/OSM": "OlSourceOSM", - "ol/source/TileWMS": "OlTileWmsSource", - "ol/source/Vector": "OlSourceVector", - "ol/source/XYZ": "XYZ", - "ol/style": "style", - "ol/style/Fill": "OlStyleFill", - "ol/style/Stroke": "OlStyleStroke", - "ol/style/Style": "OlStyleStyle", - "papaparse": "papaparse", - "proj4": "proj4" - } - }, - "assets": ["assets"] -} diff --git a/projects/wave-core/package.json b/projects/wave-core/package.json deleted file mode 100644 index 64129d34..00000000 --- a/projects/wave-core/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@umr-dbs/wave-core", - "version": "0.2.11", - "repository": { - "type": "git", - "url": "git://github.com/umr-dbs/wave.git" - }, - "publishConfig": { - "registry": "https://npm.pkg.github.com/" - }, - "peerDependencies": { - "@angular/cdk": "~10.2.4", - "@angular/common": "^10.1.5", - "@angular/core": "^10.1.5", - "@angular/forms": "~10.1.5", - "@angular/material": "~10.2.4", - "codemirror": "~5.58.1", - "d3": "~5.16.0", - "dagre": "~0.8.5", - "dagre-d3": "~0.6.4", - "immutable": "~4.0.0-rc.12", - "moment": "~2.29.1", - "ngx-color-picker": "~9.0.0", - "ol": "~6.4.3", - "papaparse": "~5.3.0", - "proj4": "~2.6.2", - "tslib": "^1.14.0" - } -} diff --git a/projects/wave-core/src/lib/colors/color-breakpoint-component/color-breakpoint.component.html b/projects/wave-core/src/lib/colors/color-breakpoint-component/color-breakpoint.component.html deleted file mode 100644 index dadc6bc5..00000000 --- a/projects/wave-core/src/lib/colors/color-breakpoint-component/color-breakpoint.component.html +++ /dev/null @@ -1,38 +0,0 @@ -
- - - - - - - -
- {{ colorBreakpoint?.value }} -
-
- - - - - - -
diff --git a/projects/wave-core/src/lib/colors/color-breakpoint-component/color-breakpoint.component.scss b/projects/wave-core/src/lib/colors/color-breakpoint-component/color-breakpoint.component.scss deleted file mode 100644 index 3b4d0375..00000000 --- a/projects/wave-core/src/lib/colors/color-breakpoint-component/color-breakpoint.component.scss +++ /dev/null @@ -1,8 +0,0 @@ -.colorizerEntries { - font-size: 0.8rem; -} - -mat-form-field >>> .color_cell { - color: black !important; - text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff !important; -} diff --git a/projects/wave-core/src/lib/colors/color-breakpoint-component/color-breakpoint.component.ts b/projects/wave-core/src/lib/colors/color-breakpoint-component/color-breakpoint.component.ts deleted file mode 100644 index 521acd94..00000000 --- a/projects/wave-core/src/lib/colors/color-breakpoint-component/color-breakpoint.component.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { - Component, - ChangeDetectionStrategy, - ChangeDetectorRef, - AfterViewInit, - Input, - forwardRef, - OnChanges, - SimpleChanges, -} from '@angular/core'; - -import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; -import {ColorBreakpoint} from '../color-breakpoint.model'; -import {Color, stringToRgbaStruct} from '../color'; - -@Component({ - selector: 'wave-color-breakpoint', - templateUrl: './color-breakpoint.component.html', - styleUrls: ['./color-breakpoint.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - providers: [{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ColorBreakpointInputComponent), multi: true}], -}) -export class ColorBreakpointInputComponent implements ControlValueAccessor, AfterViewInit, OnChanges { - @Input() disabledAttribute: false; - @Input() disabledColor: false; - @Input() inputType: 'number' | 'string' = 'number'; - @Input() attributePlaceholder = 'attribute'; - @Input() colorPlaceholder: 'color'; - - private _colorBreakpoint: ColorBreakpoint; - onTouched: () => void; - onChange: (_: ColorBreakpoint) => void = undefined; - - constructor(private changeDetectorRef: ChangeDetectorRef) {} - - get colorBreakpoint(): ColorBreakpoint { - return this._colorBreakpoint; - } - - // set accessor including call the onchange callback - set colorBreakpoint(brk: ColorBreakpoint) { - if (brk && !brk.equals(this._colorBreakpoint)) { - this._colorBreakpoint = brk; - } - } - - updateValue(value: number | string) { - // TODO: should this really clone? - if (value && value !== this.colorBreakpoint.value) { - if (this.inputType === 'number' && typeof value === 'string') { - this.colorBreakpoint.setValue(parseFloat(value as string)); - } else { - this.colorBreakpoint.setValue(value); - } - this.propagateChange(); - } - } - - updateColor(color: string) { - // TODO: should this really clone? - if (color) { - const clr = Color.fromRgbaLike(stringToRgbaStruct(color)); - if (!clr.equals(this._colorBreakpoint.rgba)) { - this.colorBreakpoint.setColor(clr); - } - this.propagateChange(); - } - } - - ngAfterViewInit() { - // setTimeout(() => this.changeDetectorRef.markForCheck(), 0); - } - - ngOnChanges(changes: SimpleChanges) { - for (const propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - case 'inputType': - case 'attributePlaceholder': - case 'colorPlaceholder': { - this.changeDetectorRef.markForCheck(); - break; - } - - default: { - } // DO NOTHING - } - } - } - - // Set touched on blur - onBlur() { - this.onTouched(); - } - - writeValue(brk: ColorBreakpoint): void { - this.colorBreakpoint = brk; - } - - registerOnChange(fn: (_: ColorBreakpoint) => void): void { - this.onChange = fn; - this.propagateChange(); - } - - registerOnTouched(fn: () => void): void { - this.onTouched = fn; - } - - private propagateChange() { - if (this.onChange && this.colorBreakpoint) { - this.onChange(this.colorBreakpoint.clone()); - } - } -} diff --git a/projects/wave-core/src/lib/colors/color-breakpoint.model.ts b/projects/wave-core/src/lib/colors/color-breakpoint.model.ts deleted file mode 100644 index 70721f6d..00000000 --- a/projects/wave-core/src/lib/colors/color-breakpoint.model.ts +++ /dev/null @@ -1,108 +0,0 @@ -import {Color, RgbaLike, RgbaStruct} from './color'; - -export type BreakPointValue = string | number; - -export interface ColorBreakpointDict { - value: BreakPointValue; - rgba: RgbaLike; -} - -/** - * A ColorBreakpoint is a tuple consisting of value and RGBA. - */ -export class ColorBreakpoint implements ColorBreakpointDict { - value: BreakPointValue; - rgba: Color; - - constructor(config: ColorBreakpointDict) { - this.rgba = Color.fromRgbaLike(config.rgba); - this.value = config.value; - } - - /** - * Clones the ColorBreakpoint - */ - clone(): ColorBreakpoint { - return new ColorBreakpoint({ - value: this.value, - rgba: this.rgba.clone(), - }); - } - - /** - * Clones the ColorBreakpoint and replaces the color. - */ - cloneWithColor(color: RgbaLike): ColorBreakpoint { - const cln = this.clone(); - cln.setColor(color); - return cln; - } - - /** - * Clones the ColorBreakpoint and replaces the value. - */ - cloneWithValue(value: BreakPointValue): ColorBreakpoint { - const cln = this.clone(); - cln.setValue(value); - return cln; - } - - /** - * Transforms the ColorBreakpoint int a ColorBreakpointDict. - */ - toDict(): ColorBreakpointDict { - return { - value: this.value, - rgba: this.rgba.rgbaTuple(), - }; - } - - /** - * Sets the color to the provided value. - */ - setColor(color: RgbaLike) { - this.rgba = Color.fromRgbaLike(color); - } - - /** - * Sets the value of the ColorBreakpoint to the provided value. - */ - setValue(value: BreakPointValue) { - this.value = value; - } - - /** - * Returns true if the value is a number. - */ - valueIsNumber(): boolean { - return typeof this.value === 'number'; - } - - /** - * Tests a ColorBreakpoint for equality with another one. - */ - equals(other: ColorBreakpoint): boolean { - return other && this.rgba.equals(other.rgba) && this.value === other.value; - } - - /** - * Transforms the ColorBreakpoint into a representation understood by Mapping's colorizer. - */ - asMappingRasterColorizerBreakpoint(): IMappingRasterColorizerBreakpoint { - return { - value: this.value as number, // TODO: handle cases where this might be a string? - r: this.rgba.r, - g: this.rgba.g, - b: this.rgba.b, - a: this.rgba.a * 255, // TODO: mapping uses alpha values from 0-255 change this? - }; - } -} - -/** - * The json representation expected by mapping. - */ -export interface IMappingRasterColorizerBreakpoint extends RgbaStruct { - value: number; - name?: string; -} diff --git a/projects/wave-core/src/lib/colors/color.ts b/projects/wave-core/src/lib/colors/color.ts deleted file mode 100644 index 217e9368..00000000 --- a/projects/wave-core/src/lib/colors/color.ts +++ /dev/null @@ -1,223 +0,0 @@ -export interface RgbaStruct { - r: number; - g: number; - b: number; - a: number; -} - -interface RgbStruct { - r: number; - g: number; - b: number; -} - -export type RgbaTuple = [number, number, number, number]; -export type RgbTuple = [number, number, number]; -export type RgbaLike = RgbaTuple | RgbTuple | RgbaStruct | RgbStruct | Color | IRgba | string; - -/** - * An interface for types representing a Rgba color - */ -export interface IRgba { - rgbaTuple(): RgbaTuple; - rgbaStruct(): RgbaStruct; - rgbaCssString(): string; -} - -/** - * Color class representing colors - */ -export class Color implements IRgba, RgbaStruct { - r: number; - g: number; - b: number; - a: number; - - constructor(config: RgbaStruct) { - this.r = config.r; - this.g = config.g; - this.b = config.b; - this.a = config.a; - } - - rgbaStruct(): RgbaStruct { - return this as RgbaStruct; - } - - rgbaTuple(): RgbaTuple { - return [this.r, this.g, this.b, this.a]; - } - - rgbTuple(): RgbTuple { - return [this.r, this.g, this.b]; - } - - rgbaCssString(): string { - return Color.rgbaToCssString(this); - } - - clone(): Color { - return new Color({ - r: this.r, - g: this.g, - b: this.b, - a: this.a, - }); - } - - equals(other: RgbaLike) { - const o = Color.fromRgbaLike(other); - return this.r === o.r && this.g === o.g && this.b === o.b && this.a === o.a; - } - - static rgbaToCssString(rgba: RgbaLike): string { - const temp = Color.fromRgbaLike(rgba, false).rgbaStruct(); - return `rgba(${temp.r.toString()}, ${temp.g.toString()}, ${temp.b.toString()}, ${temp.a.toString()})`; - } - - static rgbaTupleToStruct(rgbaTuple: RgbaTuple | RgbTuple): RgbaStruct { - if (rgbaTuple.length < 3 || rgbaTuple.length > 4) { - throw new Error('Invalid RGB(A) tuple size!'); - } - - const alpha = rgbaTuple.length < 4 ? 1.0 : rgbaTuple[3]; - return {r: rgbaTuple[0], g: rgbaTuple[1], b: rgbaTuple[2], a: alpha}; - } - - /** - * Creates a Color instance from RgbaLike Types. - * @param {RgbaLike} rgba: the rgba like input - * @param {boolean} clone: clone if already an instance of Color. Defaults to TRUE! - * @returns {Color} - */ - static fromRgbaLike(rgba: RgbaLike, clone: boolean = true): Color { - if (!rgba) { - // return some default on empty deserialization - return BLACK; - } - - if (rgba instanceof Color) { - if (clone) { - return rgba.clone(); - } - return rgba; - } - - if (rgba instanceof Array) { - return new Color(Color.rgbaTupleToStruct(rgba)); - } - - if ((rgba).rgbaStruct) { - return new Color((rgba).rgbaStruct()); - } - - if ((rgba).a || (rgba).a === 0) { - return new Color(rgba); - } - - if ((rgba).r) { - const rgb = rgba as RgbStruct; - return new Color({ - r: rgb.r, - g: rgb.g, - b: rgb.b, - a: 1.0, - }); - } - /* - if (isString(rgba)) { - return new Color(stringToRgbaStruct(rgba as string)) - } -*/ - console.error('ERROR Color.fromRgbaLike', rgba); - - throw new Error('invalid RgbaLike ' + rgba.toString()); - } - - /** - * Interpolates between two colors - * @param a: first Color -> 0 - * @param b: second Color -> 1 - * @param value: value between 0 and 1 - */ - static interpolate(a: RgbaLike, b: RgbaLike, fraction: number): Color { - const ra = Color.fromRgbaLike(a, false); - const rb = Color.fromRgbaLike(b, false); - if (fraction === 0) { - return ra; - } - if (fraction === 1) { - return rb; - } - if (ra.equals(rb)) { - return ra; - } - const clr = { - r: ra.r * (1 - fraction) + rb.r * fraction, - g: ra.g * (1 - fraction) + rb.g * fraction, - b: ra.b * (1 - fraction) + rb.b * fraction, - a: ra.a * (1 - fraction) + rb.a * fraction, - }; - return Color.fromRgbaLike(clr, false); - } - - static colorDifference(a: RgbaLike, b: RgbaLike): number { - const ra = Color.fromRgbaLike(a, false).rgbTuple(); - const rb = Color.fromRgbaLike(b, false).rgbTuple(); - - return ra.map((baseColor, i) => Math.pow(baseColor - rb[i], 2)).reduce((acc, value) => acc + value); - } -} - -export const BLACK = Color.fromRgbaLike([0, 0, 0, 1]); -export const WHITE = Color.fromRgbaLike([255, 255, 255, 1]); -export const TRANSPARENT = Color.fromRgbaLike([0, 0, 0, 0]); - -/** - * Should a string also be RgbaLike? - * @param {string} rgbaCssString - * @returns {RgbaStruct} - */ -export function stringToRgbaStruct(rgbaCssString: string): RgbaStruct { - if (rgbaCssString === undefined || rgbaCssString === '') { - throw new Error('cant parse empty string into a color'); - } - - let rgba = - rgbaCssString.match(/^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+.*\d*)\s*\)$/i) || - rgbaCssString.match(/^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i) || - rgbaCssString.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i); - - if (rgba) { - return { - r: parseInt(rgba[1], 10), - g: parseInt(rgba[2], 10), - b: parseInt(rgba[3], 10), - a: rgba[4] === undefined ? 1 : parseFloat(rgba[4]), - }; - } - - let threeDigit = rgbaCssString.match(/^#([0-9a-f]{3})$/i)[1]; - if (threeDigit) { - // in three-character format, each value is multiplied by 0x11 to give an - // even scale fromRgbaLike 0x00 to 0xff - return { - r: parseInt(threeDigit.charAt(0), 16) * 0x11, - g: parseInt(threeDigit.charAt(1), 16) * 0x11, - b: parseInt(threeDigit.charAt(2), 16) * 0x11, - a: 1, - }; - } - - let sixDigit = rgbaCssString.match(/^#([0-9a-f]{6})$/i)[1]; - if (sixDigit) { - return { - r: parseInt(sixDigit.substr(0, 2), 16), - g: parseInt(sixDigit.substr(2, 2), 16), - b: parseInt(sixDigit.substr(4, 2), 16), - a: 1, - }; - } - - throw new Error('cant parse string into a color' + rgbaCssString); -} diff --git a/projects/wave-core/src/lib/colors/colorizer-data.model.ts b/projects/wave-core/src/lib/colors/colorizer-data.model.ts deleted file mode 100644 index f91bd19b..00000000 --- a/projects/wave-core/src/lib/colors/colorizer-data.model.ts +++ /dev/null @@ -1,307 +0,0 @@ -import {BreakPointValue, ColorBreakpoint, ColorBreakpointDict, IMappingRasterColorizerBreakpoint} from './color-breakpoint.model'; -import {Color} from './color'; - -/** - * DEPRECATED - */ -export interface DeprecatedMappingColorizerDoNotUse { - interpolation: string; - breakpoints: Array<[number, string, string]>; - result?: string | number; -} - -/** - * The colorizer types supported by Mapping. - */ -export type ColorizerType = 'gradient' | 'logarithmic' | 'palette' | 'rgba_composite'; - -/** - * An interface for the data representing a colorizer. - */ -export interface IColorizerData { - breakpoints: Array; - type?: ColorizerType; -} - -/** - * The interface for colorizers supported by Mapping. - */ -export interface MappingRasterColorizerDict { - breakpoints: Array; - type?: ColorizerType; - nodata?: IMappingRasterColorizerBreakpoint; - default?: IMappingRasterColorizerBreakpoint; -} - -/** - * The information within ColorizerData allows colorization of vector and raster data. - */ -export class ColorizerData implements IColorizerData { - breakpoints: Array; - type: ColorizerType; - - /** - * Generate a new gray scale colorizer for values between min and max. - */ - static grayScaleColorizer(minMax: {min: number; max: number}): ColorizerData { - const saveMin = minMax.min ? minMax.min : -1000; - const saveMax = minMax.max ? minMax.max : 1000; - const saveCenter = (saveMin + saveMax) / 2.0; - - const min_br: ColorBreakpointDict = { - value: saveMin, - rgba: Color.fromRgbaLike({ - r: 0, - g: 0, - b: 0, - a: 1, - }), - }; - - const mid_br: ColorBreakpointDict = { - value: saveCenter, - rgba: Color.fromRgbaLike({ - r: 128, - g: 128, - b: 128, - a: 1, - }), - }; - - const max_br: ColorBreakpointDict = { - value: saveMax, - rgba: Color.fromRgbaLike({ - r: 255, - g: 255, - b: 255, - a: 1, - }), - }; - - return new ColorizerData({ - breakpoints: [min_br, mid_br, max_br], - type: 'gradient', - }); - } - - /** - * Deserialization for IColorizerData into ColorizerData. - */ - static fromDict(dict: IColorizerData): ColorizerData { - if (!dict) { - // return some default value in case of empty deserialization - return ColorizerData.grayScaleColorizer({ - min: 0, - max: 100, - }); - } - - return new ColorizerData(dict); - } - - /** - * Generates an instance of ColorizerData without any breakpoints. - */ - static empty(): ColorizerData { - return new ColorizerData({ - breakpoints: [], - type: 'gradient', - }); - } - - /** - * Check if an instance of (I)ColorizerData is valid. - */ - static is_valid(colorizerData: IColorizerData) { - return colorizerData.breakpoints.length >= 2; - } - - /** - * The constructor for ColorizerData. - */ - constructor(config: IColorizerData) { - this.breakpoints = config.breakpoints ? config.breakpoints.map((br) => new ColorBreakpoint(br)) : []; - this.type = config.type ? config.type : 'gradient'; - } - - /** - * Removes all breakpoints. - */ - clear() { - this.breakpoints = []; - } - - /** - * Adds a breakpoint to the end of the list. - */ - addBreakpoint(brk: ColorBreakpointDict) { - this.breakpoints.push(new ColorBreakpoint(brk)); - } - - /** - * Adds a breakpoint at position i in the list. - */ - addBreakpointAt(i: number, brk: ColorBreakpoint) { - this.breakpoints.splice(i, 0, brk); - } - - /** - * Removes the breakpoint at position i in the list. - */ - removeBreakpointAt(i: number) { - this.breakpoints.splice(i, 1); - } - - /** - * Updates the ColorBreakpoint at position i. - */ - updateBreakpointAt(i: number, brk: ColorBreakpoint): boolean { - const equal = this.getBreakpointAt(i).equals(brk); - if (brk && !equal) { - this.breakpoints[i] = brk; - return true; - } - return false; - } - - /** - * Returns the ColorBreakpoint at position i. - */ - getBreakpointAt(i: number): ColorBreakpoint { - return this.breakpoints[i]; - } - - /** - * Get a (new) breakpoint for a value. - */ - getBreakpointForValue(value: BreakPointValue, interpolate: boolean = false): ColorBreakpoint | undefined { - if (!value || !this.breakpoints || this.breakpoints.length <= 0) { - return undefined; - } - - const isGradient = this.type === 'gradient'; - const isNumber = typeof value === 'number'; - const firstBrkIsNumber = this.getBreakpointAt(0).valueIsNumber(); // TODO: this is prob. not always the correct type. - const lookUpValue = firstBrkIsNumber && !isNumber ? parseFloat(value as string) : value; - const isLookupNumber = typeof lookUpValue === 'number'; - - let brk_index = -1; - for (let index = 0; index < this.breakpoints.length; index++) { - const brk_i = this.breakpoints[index]; - if (isLookupNumber && brk_i.value <= lookUpValue) { - brk_index = index; - } else if (brk_i.value === lookUpValue) { - brk_index = index; - } - } - const brk = this.breakpoints[brk_index]; - const validBrk = brk_index >= 0 && (this.breakpoints.length > 1 || brk.value === lookUpValue); - const isLastBrk = brk_index >= this.breakpoints.length - 1; - - if (!validBrk) { - return undefined; - } - - if (!interpolate || isLastBrk || brk.value === lookUpValue || !isGradient) { - return brk; - } - - // handling gradients for numbers... - const brk_next = this.breakpoints[brk_index + 1]; - if (typeof lookUpValue === 'number' && typeof brk.value === 'number' && typeof brk_next.value === 'number') { - const diff = lookUpValue - brk.value; - const frac_diff = diff / (brk_next.value - brk.value); - const color = Color.interpolate(brk.rgba, brk_next.rgba, frac_diff); - - return new ColorBreakpoint({ - rgba: color, - value: brk.value + diff, - }); - } - - return undefined; - } - - get firstBreakpoint(): ColorBreakpoint | undefined { - return !this.breakpoints || this.isEmpty() ? undefined : this.breakpoints[0]; - } - - get lastBreakpoint(): ColorBreakpoint | undefined { - return !this.breakpoints || this.isEmpty() ? undefined : this.breakpoints[this.breakpoints.length - 1]; - } - - /** - * Checks if the list of breakpoints is empty. - */ - isEmpty(): boolean { - return !this.breakpoints || this.breakpoints.length === 0; - } - - /** - * Update the type of the ColorizerData. - */ - updateType(type: ColorizerType): boolean { - if (type && (!this.type || type !== this.type)) { - this.type = type; - return true; - } - return false; - } - - /** - * Returns a clone of the ColorizerData. - */ - clone(): ColorizerData { - return new ColorizerData(this.toDict() as IColorizerData); - } - - /** - * Compares this ColorizerData with another one. - */ - equals(other: ColorizerData): boolean { - if (!other || this.breakpoints.length !== other.breakpoints.length || this.type !== other.type) { - return false; - } - - for (let i = 0; i < this.breakpoints.length; i++) { - if (!this.getBreakpointAt(i).equals(other.getBreakpointAt(i))) { - return false; - } - } - - return true; - } - - /** - * Transforms ColorizerData into an interface object. - */ - toDict(): IColorizerData { - return { - breakpoints: this.breakpoints.map((br) => br.toDict()), - type: this.type, - }; - } - - /** - * Generates a ColorizerData instance from a MappingColorizer. - */ - static fromMappingColorizerData(mcd: MappingRasterColorizerDict): ColorizerData { - return new ColorizerData({ - type: !mcd || !mcd.type ? 'gradient' : mcd.type, - breakpoints: - !mcd || !mcd.breakpoints - ? [] - : mcd.breakpoints.map((br) => { - return new ColorBreakpoint({ - rgba: { - r: br.r, - g: br.g, - b: br.b, - a: br.a ? br.a : 1.0, - }, - value: br.value, - }); - }), - }); - } -} diff --git a/projects/wave-core/src/lib/colors/colorizer-editor/colorizer-editor.component.html b/projects/wave-core/src/lib/colors/colorizer-editor/colorizer-editor.component.html deleted file mode 100644 index 07eaffb9..00000000 --- a/projects/wave-core/src/lib/colors/colorizer-editor/colorizer-editor.component.html +++ /dev/null @@ -1,36 +0,0 @@ -
-
- - - linear gradient - logarithmic gradient - palette - - -
- -
- -
- - -
- - -
-
-
-
-
diff --git a/projects/wave-core/src/lib/colors/colorizer-editor/colorizer-editor.component.scss b/projects/wave-core/src/lib/colors/colorizer-editor/colorizer-editor.component.scss deleted file mode 100644 index 6039fbff..00000000 --- a/projects/wave-core/src/lib/colors/colorizer-editor/colorizer-editor.component.scss +++ /dev/null @@ -1,7 +0,0 @@ -.colorizerEntries { -} - -mat-form-field >>> .color_cell { - color: black !important; - text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff !important; -} diff --git a/projects/wave-core/src/lib/colors/colorizer-editor/colorizer-editor.component.ts b/projects/wave-core/src/lib/colors/colorizer-editor/colorizer-editor.component.ts deleted file mode 100644 index c5577316..00000000 --- a/projects/wave-core/src/lib/colors/colorizer-editor/colorizer-editor.component.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { - Component, - Input, - ChangeDetectionStrategy, - OnChanges, - SimpleChanges, - forwardRef, - ChangeDetectorRef, - AfterViewInit, -} from '@angular/core'; - -import {ColorizerData, ColorizerType} from '../colorizer-data.model'; -import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms'; -import {ColorBreakpoint} from '../color-breakpoint.model'; - -/** - * The ColorizerEditorComponent is the main dialog for editing ColorizerData / ColorBreakpoints - */ -@Component({ - selector: 'wave-colorizer-editor', - templateUrl: 'colorizer-editor.component.html', - styleUrls: ['colorizer-editor.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - providers: [{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ColorizerEditorComponent), multi: true}], -}) -export class ColorizerEditorComponent implements ControlValueAccessor, OnChanges { - private _colorizer: ColorizerData = undefined; - onTouched: () => void; - onChange: (_: ColorizerData) => void = undefined; - - get colorizer(): ColorizerData { - return this._colorizer; - } - - set colorizer(clr: ColorizerData) { - if (clr && !clr.equals(this._colorizer)) { - this._colorizer = clr.clone(); - this.notify(); - } - } - - /** - * Toggles the colorizer type selector. Default = true. - */ - @Input() showTypeSelect = true; - - /** - * Toggles the name hinting column. Default = false. - */ - @Input() showNameHintColumn = false; - - /** - * Switches the attribute input to disabled. Default = false; - */ - @Input() disabledAttribute = false; - - /** - * Switches the color input to disabled. Default = false; - */ - @Input() disabledColor = false; - - /** - * The data type of the attribute input. Default = number. - */ - @Input() inputType: 'number' | 'string' = 'number'; - - /** - * The attribute input placeholder string. - */ - @Input() attributePlaceholder = 'attribute'; - - /** - * the color input placeholder string. - */ - @Input() colorPlaceholder = 'color'; - - /** - * The constructor. - */ - constructor(private changeDetectorRef: ChangeDetectorRef) {} - - ngOnChanges(changes: SimpleChanges) { - for (const propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - case 'inputType': - case 'attributePlaceholder': - case 'colorPlaceholder': { - this.changeDetectorRef.markForCheck(); - break; - } - - default: { - // DO NOTHING - } - } - } - } - - /** - * Update the colorizer type of the colorizer data. - */ - updateType(type: ColorizerType) { - if (type && this._colorizer) { - const diff = this._colorizer.updateType(type); - if (diff) { - this.notify(); - } - } - } - - /** - * Update the breakpoint in the colorizer data at position i. - */ - updateBreakpointAt(i: number, brk: ColorBreakpoint) { - // TODO: check if this is valid - if (this._colorizer && this._colorizer.breakpoints.length > i) { - const diff = this._colorizer.updateBreakpointAt(i, brk); - this.notify(); - } - } - - /** - * Add a new breakpoint at position i. Clones the next breakpoint if possible. - */ - addBreakpointAt(i: number) { - if (this._colorizer && this._colorizer.breakpoints.length > i) { - this._colorizer.addBreakpointAt(i, this._colorizer.getBreakpointAt(i).clone()); - } else { - this._colorizer.addBreakpoint(this._colorizer.getBreakpointAt(i)); - } - this.notify(); - } - - /** - * Removes the breakpoint at position i. - */ - removeBreakpointAt(i: number) { - if (this._colorizer && this._colorizer.breakpoints.length > i) { - this._colorizer.removeBreakpointAt(i); - this.notify(); - } - } - - /** - * Sends the wip colorizer to a registred reciever. - */ - notify() { - if (this.onChange && this._colorizer) { - this.onChange(this._colorizer.clone()); - } - } - - registerOnChange(fn: (_: ColorizerData) => void): void { - if (fn) { - this.onChange = fn; - this.notify(); - } - } - - registerOnTouched(fn: () => void): void { - if (fn) { - this.onTouched = fn; - } - } - - writeValue(colorizerData: ColorizerData): void { - this.colorizer = colorizerData; - } -} diff --git a/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-colorizer.component.html b/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-colorizer.component.html deleted file mode 100644 index b9c58739..00000000 --- a/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-colorizer.component.html +++ /dev/null @@ -1,93 +0,0 @@ -
-
-
- - Min - - - Specify a minimum and a maximum. - - - Min value must be greater then {{ form.controls.colormapStepScales?.value.requiresValueAbove }} - - - - Max - - - The maximum must be greater or equal to the minimum. - - - Max value must be lower then {{ form.controls.colormapStepScales?.value.requiresValueBelow }} - - -
- - - Colormap name - - - - {{ colormapName }} - - - - - Reverse colormap - - - Step distribution - - - {{ colormapStepScale.stepScaleName }} - - - - -
- - - - - - - - - - -
Color steps - - - {{ form.controls.colormapSteps.value }}
Preview - invalid configuration -
-
-
- - - - -
-
diff --git a/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-colorizer.component.scss b/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-colorizer.component.scss deleted file mode 100644 index 1b5e759d..00000000 --- a/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-colorizer.component.scss +++ /dev/null @@ -1,42 +0,0 @@ -table { - width: 100%; - font-size: 0.8em; -} - -mat-divider { - padding-bottom: 1rem; -} - -td:first-child, -td:last-child { - width: 1%; - white-space: nowrap; -} - -mat-slider { - min-width: unset; - width: 100%; -} - -.component_container { - width: 100%; - padding-top: 5px; -} - -.colorizer_preview { - min-height: 20px; - border: #000 solid 1px; -} - -.colorizer_option_preview { - min-height: 20px; - border: #000 solid 1px; - width: 30%; - display: inline-block; - margin: auto; - vertical-align: middle; -} - -.fill_width { - width: 100%; -} diff --git a/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-colorizer.component.ts b/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-colorizer.component.ts deleted file mode 100644 index 5b73145e..00000000 --- a/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-colorizer.component.ts +++ /dev/null @@ -1,248 +0,0 @@ -import { - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - EventEmitter, - Input, - OnChanges, - OnDestroy, - OnInit, - Output, - SimpleChanges, -} from '@angular/core'; -import {ColorizerData} from '../colorizer-data.model'; -import { - BoundedColormapStepScale, - COLORMAP_STEP_SCALES_WITH_BOUNDS, - COLORMAP_NAMES, - Colormap, - ColormapNames, -} from '../colormaps/colormap.model'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {valueRelation, WaveValidators} from '../../util/form.validators'; -import {Subscription} from 'rxjs'; - -/** - * The ColormapColorizerComponent is a dialog to generate ColorizerData from colormaps. - */ -@Component({ - selector: 'wave-colormap-colorizer', - templateUrl: 'colormap-colorizer.component.html', - styleUrls: ['colormap-colorizer.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ColormapColorizerComponent implements OnInit, OnDestroy, OnChanges { - /** - * Emmits new ColorizerData instances generated from user input. - */ - @Output() colormapColorizerData = new EventEmitter(); - - /** - * Number of breakpoints used in the ColorizerData. - */ - @Input() defaultNumberOfSteps = 16; - - /** - * Max allowed number of breakpoints in the ColorizerData. - */ - @Input() maxColormapSteps = 16; - - /** - * Sets the min value used for ColorizerData generation. - */ - @Input() minValue = 0; - - /** - * Sets the max value used for ColorizerData generation. - */ - @Input() maxValue = 1; - - /** - * Sends the min value selected in the ui. - */ - @Output() minValueChange = new EventEmitter(); - - /** - * Sends the max value selected in the ui. - */ - @Output() maxValueChange = new EventEmitter(); - - // make colormap names and step scales available to the tamplate. - readonly colormapNames = COLORMAP_NAMES; - readonly boundedColormapStepScales = COLORMAP_STEP_SCALES_WITH_BOUNDS; - - /** - * The form control used in the template. - */ - form: FormGroup; - - /** - * The local (work-in-progress) ColorizerData. - */ - colorizerData: ColorizerData = Colormap.createColorizerDataWithName(this.colormapNames[0], 0, 1); - - private subscriptions: Array = []; - - constructor(private changeDetectorRef: ChangeDetectorRef, private formBuilder: FormBuilder) { - this.form = formBuilder.group( - { - bounds: formBuilder.group( - { - min: [0], - max: [1], - }, - { - validators: [WaveValidators.minAndMax('min', 'max', {checkBothExist: true})], - }, - ), - colormapName: [this.colormapNames[0], [Validators.required]], - colormapSteps: [this.defaultNumberOfSteps, [Validators.required, Validators.min(2)]], - colormapStepScales: [this.boundedColormapStepScales[0]], - colormapReverseColors: [false], - }, - { - validators: [ - valueRelation( - (c) => c.get('bounds').get('min').value, - (c) => c.get('colormapStepScales').value['requiresValueAbove'], - {checkEqual: true, checkBelow: true}, - ), - valueRelation( - (c) => c.get('bounds').get('max').value, - (c) => c.get('colormapStepScales').value['requiresValueBelow'], - {checkEqual: true, checkAbove: true}, - ), - ], - }, - ); - } - - /** - * Replace the min and max values. - */ - patchMinMaxValues(min: number, max: number) { - const patchConfig: {min?: number; max?: number} = {}; - const boundsMin: number = this.form.controls['bounds'].value.min; - const boundsMax: number = this.form.controls['bounds'].value.max; - - if (min !== undefined && min !== boundsMin) { - patchConfig.min = min; - } - - if (max !== undefined && max !== boundsMax) { - patchConfig.max = max; - } - - this.form.controls.bounds.patchValue(patchConfig); - } - - private checkValidConfig() { - const colormapName: ColormapNames = this.form.controls['colormapName'].value; - const colormapSteps: number = this.form.controls['colormapSteps'].value; - const boundedColormapStepScales: BoundedColormapStepScale = this.form.controls['colormapStepScales'].value; - const boundsMin: number = this.form.controls['bounds'].value.min; - const boundsMax: number = this.form.controls['bounds'].value.max; - - if (!COLORMAP_NAMES.find((x) => x === colormapName)) { - return false; - } - if (colormapSteps > this.maxColormapSteps) { - return false; - } - if (boundsMin >= boundsMax) { - return false; - } - if (boundedColormapStepScales.requiresValueAbove && boundsMin <= boundedColormapStepScales.requiresValueAbove) { - return false; - } - if (boundedColormapStepScales.requiresValueBelow && boundsMax >= boundedColormapStepScales.requiresValueBelow) { - return false; - } - return true; - } - - /** - * Clears the local colorizer data. - */ - removeColorizerData() { - this.colorizerData = undefined; - } - - private updateColorizerData() { - if (!this.checkValidConfig()) { - this.colorizerData = undefined; - return; - } - const colormapName: ColormapNames = this.form.controls['colormapName'].value; - const colormapSteps: number = this.form.controls['colormapSteps'].value; - const boundedColormapStepScales: BoundedColormapStepScale = this.form.controls['colormapStepScales'].value; - const boundsMin: number = this.form.controls['bounds'].value.min; - const boundsMax: number = this.form.controls['bounds'].value.max; - const reverseColormap: boolean = this.form.controls['colormapReverseColors'].value; - - const colorizerData = Colormap.createColorizerDataWithName( - colormapName, - boundsMin, - boundsMax, - colormapSteps, - boundedColormapStepScales.stepScaleName, - reverseColormap, - ); - - this.colorizerData = colorizerData; - } - - /** - * Apply a new color table to the colorizer data. - */ - applyNewColorTable(_: any) { - if (this.colorizerData) { - this.colormapColorizerData.emit(this.colorizerData); - } - } - - ngOnInit(): void { - const sub = this.form.valueChanges.subscribe((_) => { - if (this.form.invalid) { - this.removeColorizerData(); - } - this.updateColorizerData(); - }); - this.subscriptions.push(sub); - - if (this.minValue && this.maxValue) { - this.patchMinMaxValues(this.minValue, this.maxValue); - } - - const subMinMax = this.form.controls['bounds'].valueChanges.subscribe((x) => { - if (Number.isFinite(x.min)) { - this.minValueChange.emit(x.min.value); - } - if (Number.isFinite(x.max)) { - this.maxValueChange.emit(x.max.value); - } - }); - this.subscriptions.push(subMinMax); - } - - ngOnDestroy(): void { - this.subscriptions.forEach((s) => s.unsubscribe()); - } - - ngOnChanges(changes: SimpleChanges): void { - for (const propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - case 'minValue': - case 'maxValue': { - this.patchMinMaxValues(this.minValue, this.maxValue); - break; - } - - default: { - // DO NOTHING - } - } - } - } -} diff --git a/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-name-to-colorizer-data.pipe.ts b/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-name-to-colorizer-data.pipe.ts deleted file mode 100644 index 8cd9d162..00000000 --- a/projects/wave-core/src/lib/colors/colormap-colorizer/colormap-name-to-colorizer-data.pipe.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {Pipe, PipeTransform} from '@angular/core'; -import {IColorizerData} from '../colorizer-data.model'; -import {Colormap, ColormapNames, ColormapStepScale} from '../colormaps/colormap.model'; - -/** - * A pipe to transform a color map into a colorizer data. - */ -@Pipe({name: 'waveColormapNameToColorizerData'}) -export class ColormapNameToColorizerDataPipe implements PipeTransform { - transform( - colormapName: ColormapNames, - min: number = 0, - max: number = 0, - steps: number = 10, - stepScale: ColormapStepScale = 'linear', - ): IColorizerData { - return Colormap.createColorizerDataWithName(colormapName, min, max, steps, stepScale); - } -} diff --git a/projects/wave-core/src/lib/colors/colormaps/colormap.model.ts b/projects/wave-core/src/lib/colors/colormaps/colormap.model.ts deleted file mode 100644 index 69821a00..00000000 --- a/projects/wave-core/src/lib/colors/colormaps/colormap.model.ts +++ /dev/null @@ -1,262 +0,0 @@ -import {ColorBreakpointDict} from '../color-breakpoint.model'; -import {Color} from '../color'; -import {ColorizerData} from '../colorizer-data.model'; -import { - colormap_inferno_data, - colormap_magma_data, - colormap_plasma_data, - colormap_viridis_data, - MPL_COLORMAP_NAMES, - MplColormapName, -} from './mpl-colormaps'; -import {coolwarm_data, MORELAND_COLORMAP_NAMES, MorelandColormapName} from './moreland-colormaps'; -import { - colormap_arcon_data, - colormap_bamako_data, - colormap_batlow_data, - colormap_berlin_data, - colormap_bilbao_data, - colormap_broc_data, - colormap_broco_data, - colormap_buda_data, - colormap_corc_data, - colormap_corco_data, - colormap_davos_data, - colormap_devon_data, - colormap_grayc_data, - colormap_hawaii_data, - colormap_imola_data, - colormap_lajolla_data, - colormap_lapaz_data, - colormap_lisbon_data, - colormap_nuuk_data, - colormap_oleron_data, - colormap_oslo_data, - colormap_roma_data, - colormap_romao_data, - colormap_tofino_data, - colormap_tokyo_data, - colormap_turku_data, - colormap_vik_data, - colormap_viko_data, - SCIENTIFIC_COLORMAP_NAMES, - ScientificColormapName, -} from './scientific-colormaps/scientific-colormaps'; -import {colormap_rainbow_data, GENERIC_COLORMAP_NAMES, GenericColormapName} from './generic-colormaps'; - -/** - * Type for ColormapData / a wrapper for RGB values. - */ -export type ColormapData = Array<[number, number, number]>; - -/** - * All allowed `Colormap` names. - */ -export type ColormapNames = MplColormapName | MorelandColormapName | ScientificColormapName | GenericColormapName; - -/** - * A list of all `Colormap` names. - */ -export const COLORMAP_NAMES: Array = [ - ...MPL_COLORMAP_NAMES, - ...MORELAND_COLORMAP_NAMES, - ...SCIENTIFIC_COLORMAP_NAMES, - ...GENERIC_COLORMAP_NAMES, -]; - -/** - * The `Colormap` step scaling methods. - */ -export type ColormapStepScale = 'linear' | 'log' | 'square root' | 'square'; - -/** - * An interface for bounded step scales. E.g. log is only possible for values >= 1. - */ -export interface BoundedColormapStepScale { - stepScaleName: ColormapStepScale; - requiresValueAbove?: number; - requiresValueBelow?: number; -} - -/** - * A list of all step scales with possible bounds. - */ -export const COLORMAP_STEP_SCALES_WITH_BOUNDS: Array = [ - {stepScaleName: 'linear'}, - {stepScaleName: 'log', requiresValueAbove: 0}, - {stepScaleName: 'square root', requiresValueBelow: 5000}, - {stepScaleName: 'square', requiresValueBelow: 5000}, -]; - -/** - * Abstract class for common `Colormap` functions. - */ -export abstract class Colormap { - /** - * Resolves the `Colormap` data for a `Colormap` name. - */ - static getColormapForName(colormapName: ColormapNames): ColormapData { - switch (colormapName) { - case 'INFERNO': - return colormap_inferno_data; - case 'MAGMA': - return colormap_magma_data; - case 'PLASMA': - return colormap_plasma_data; - case 'VIRIDIS': - return colormap_viridis_data; - case 'COOLWARM': - return coolwarm_data; - case 'ARCON': - return colormap_arcon_data; - case 'BAMAKO': - return colormap_bamako_data; - case 'BATLOW': - return colormap_batlow_data; - case 'BERLIN': - return colormap_berlin_data; - case 'BILBAO': - return colormap_bilbao_data; - case 'BROC': - return colormap_broc_data; - case 'BROCO': - return colormap_broco_data; - case 'BUDA': - return colormap_buda_data; - case 'CORC': - return colormap_corc_data; - case 'CORCO': - return colormap_corco_data; - case 'DAVOS': - return colormap_davos_data; - case 'DEVON': - return colormap_devon_data; - case 'GRAYC': - return colormap_grayc_data; - case 'HAWAII': - return colormap_hawaii_data; - case 'IMOLA': - return colormap_imola_data; - case 'LAJOLLA': - return colormap_lajolla_data; - case 'LAPAZ': - return colormap_lapaz_data; - case 'LISBON': - return colormap_lisbon_data; - case 'NUUK': - return colormap_nuuk_data; - case 'OLERON': - return colormap_oleron_data; - case 'OSLO': - return colormap_oslo_data; - case 'ROMA': - return colormap_roma_data; - case 'ROMAO': - return colormap_romao_data; - case 'TOFINO': - return colormap_tofino_data; - case 'TOKYO': - return colormap_tokyo_data; - case 'TURKU': - return colormap_turku_data; - case 'VIK': - return colormap_vik_data; - case 'VIKO': - return colormap_viko_data; - case 'RAINBOW': - return colormap_rainbow_data; - } - } - - private static calculateStepScales( - stepScale: ColormapStepScale, - stepFractions: Array, - min: number, - max: number, - ): Array { - switch (stepScale) { - case 'linear': - return Colormap.linearNormInverse(stepFractions, min, max); - case 'log': - return Colormap.logNormInverse(stepFractions, min, max); - case 'square root': - return Colormap.powerNormInverse(stepFractions, min, max, 0.5); - case 'square': - return Colormap.powerNormInverse(stepFractions, min, max, 2); - } - } - - private static colormapColorToRgb(colormapColor: [number, number, number]): [number, number, number] { - return [colormapColor[0] * 255, colormapColor[1] * 255, colormapColor[2] * 255]; - } - - static createColorizerDataWithName( - colormapName: ColormapNames, - min: number, - max: number, - steps: number | undefined = 16, - stepScale: ColormapStepScale = 'linear', - reverseColors: boolean = false, - ): ColorizerData { - let colormap = Colormap.getColormapForName(colormapName); - if (reverseColors) { - colormap = [...colormap].reverse(); // use a clone since 'reverse' mutates the original array - } - const trueSteps = steps && steps <= colormap.length ? steps : colormap.length; - const colormapStepFractions = Colormap.generateLinearStepFractions(trueSteps); - const colormapValues = Colormap.calculateStepScales(stepScale, colormapStepFractions, min, max); - const breakpoints = Colormap.createColormapColorizerBreakpoints(colormap, colormapStepFractions, colormapValues); - return new ColorizerData({ - breakpoints, - type: stepScale === 'log' ? 'logarithmic' : 'gradient', - }); - } - - private static logNormInverse(stepFractions: Array, min: number, max: number): Array { - return stepFractions.map((x) => min * Math.pow(max / min, x)); - } - - private static powerNormInverse(stepFractions: Array, min: number, max: number, gamma: number = 2): Array { - return stepFractions.map((x) => Math.pow(x, 1 / gamma) * (max - min) + min); - } - - private static linearNormInverse(stepFractions: Array, min: number, max: number): Array { - return stepFractions.map((x) => min + x * (max - min)); - } - - private static createColormapColorizerBreakpoints( - colormap: ColormapData, - colorStepScales: Array, - colormapValues: Array, - ): Array { - if (!colorStepScales || !colormapValues || colorStepScales.length !== colormapValues.length || colorStepScales.length < 2) { - throw new Error('colormap creation requires colorMapStepScales and colormapValues with identical length >2'); - } - const breakpoints = new Array(colorStepScales.length); - for (let i = 0; i < colorStepScales.length; i++) { - const value = colormapValues[i]; - const colormapIndex = Math.round(colorStepScales[i] * (colormap.length - 1)); - const colorMapValue = colormap[colormapIndex]; - const color = Color.fromRgbaLike(Colormap.colormapColorToRgb(colorMapValue), false); - breakpoints[i] = { - value, - rgba: color, - }; - } - return breakpoints; - } - - private static generateLinearStepFractions(steps: number): Array { - const maxIndex = steps - 1; - const stepFractions = new Array(steps); - stepFractions[0] = 0; - stepFractions[maxIndex] = 1; - - for (let i = 1; i < maxIndex; i++) { - // fill the values between 0 and 1. - stepFractions[i] = i / maxIndex; - } - - return stepFractions; - } -} diff --git a/projects/wave-core/src/lib/colors/colormaps/generic-colormaps.ts b/projects/wave-core/src/lib/colors/colormaps/generic-colormaps.ts deleted file mode 100644 index 69b2668c..00000000 --- a/projects/wave-core/src/lib/colors/colormaps/generic-colormaps.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * The color map name. - */ -export type GenericColormapName = 'RAINBOW'; - -/** - * The list of available color map names. - */ -export const GENERIC_COLORMAP_NAMES: Array = ['RAINBOW']; - -/** - * The rainbow color map. - */ -export const colormap_rainbow_data: Array<[number, number, number]> = [ - [0.0, 0.0, 0.5], - [0.0, 0.0, 0.803], - [0.0, 0.03333, 1.0], - [0.0, 0.3, 1.0], - [0.0, 0.5666, 1.0], - [0.0, 0.8333, 1.0], - [0.1613, 1.0, 0.8064], - [0.3763, 1.0, 0.5914], - [0.5914, 1.0, 0.376], - [0.8064, 1.0, 0.1613], - [1.0, 0.9012, 0.0], - [1.0, 0.6543, 0.0], - [1.0, 0.4074, 0.0], - [1.0, 0.1605, 0.0], - [0.803, 0.0, 0.0], - [0.5, 0.0, 0.0], -]; diff --git a/projects/wave-core/src/lib/colors/colormaps/moreland-colormaps.ts b/projects/wave-core/src/lib/colors/colormaps/moreland-colormaps.ts deleted file mode 100644 index d9f94621..00000000 --- a/projects/wave-core/src/lib/colors/colormaps/moreland-colormaps.ts +++ /dev/null @@ -1,55 +0,0 @@ -import {ColormapNames} from './colormap.model'; - -/** - * This color maps are from CoolWarmFloat33.csv of "Diverging Color Maps for Scientific Visualization" by Kenneth Moreland - * on - */ - -/** - * The color map name. - */ -export type MorelandColormapName = 'COOLWARM'; - -/** - * The list of available color map names. - */ -export const MORELAND_COLORMAP_NAMES: Array = ['COOLWARM']; - -/** - * The coolwarm color map. - */ -export const coolwarm_data: Array<[number, number, number]> = [ - [0.2298057, 0.298717966, 0.753683153], - [0.26623388, 0.353094838, 0.801466763], - [0.30386891, 0.406535296, 0.84495867], - [0.342804478, 0.458757618, 0.883725899], - [0.38301334, 0.50941904, 0.917387822], - [0.424369608, 0.558148092, 0.945619588], - [0.46666708, 0.604562568, 0.968154911], - [0.509635204, 0.648280772, 0.98478814], - [0.552953156, 0.688929332, 0.995375608], - [0.596262162, 0.726149107, 0.999836203], - [0.639176211, 0.759599947, 0.998151185], - [0.681291281, 0.788964712, 0.990363227], - [0.722193294, 0.813952739, 0.976574709], - [0.761464949, 0.834302879, 0.956945269], - [0.798691636, 0.849786142, 0.931688648], - [0.833466556, 0.860207984, 0.901068838], - [0.865395197, 0.86541021, 0.865395561], - [0.897787179, 0.848937047, 0.820880546], - [0.924127593, 0.827384882, 0.774508472], - [0.944468518, 0.800927443, 0.726736146], - [0.958852946, 0.769767752, 0.678007945], - [0.96732803, 0.734132809, 0.628751763], - [0.969954137, 0.694266682, 0.579375448], - [0.966811177, 0.650421156, 0.530263762], - [0.958003065, 0.602842431, 0.481775914], - [0.943660866, 0.551750968, 0.434243684], - [0.923944917, 0.49730856, 0.387970225], - [0.89904617, 0.439559467, 0.343229596], - [0.869186849, 0.378313092, 0.300267182], - [0.834620542, 0.312874446, 0.259301199], - [0.795631745, 0.24128379, 0.220525627], - [0.752534934, 0.157246067, 0.184115123], - [0.705673158, 0.01555616, 0.150232812], -]; diff --git a/projects/wave-core/src/lib/colors/colormaps/mpl-colormaps.ts b/projects/wave-core/src/lib/colors/colormaps/mpl-colormaps.ts deleted file mode 100644 index 7d9c5010..00000000 --- a/projects/wave-core/src/lib/colors/colormaps/mpl-colormaps.ts +++ /dev/null @@ -1,1052 +0,0 @@ -/** - * The colormap data in this file are based on: - * "New matplotlib colormaps by Nathaniel J. Smith, Stefan van der Walt, and (in the case of viridis) Eric Firing." - * @see(https://github.com/BIDS/colormap/blob/master/colormaps.py) - * They are licensed under the CC0 license. - */ - -/** - * The color map names. - */ -export type MplColormapName = 'MAGMA' | 'INFERNO' | 'PLASMA' | 'VIRIDIS'; - -/** - * The list of available color map names. - */ -export const MPL_COLORMAP_NAMES: Array = ['MAGMA', 'INFERNO', 'PLASMA', 'VIRIDIS']; - -export const colormap_magma_data: Array<[number, number, number]> = [ - [0.001462, 0.000466, 0.013866], - [0.002258, 0.001295, 0.018331], - [0.003279, 0.002305, 0.023708], - [0.004512, 0.00349, 0.029965], - [0.00595, 0.004843, 0.03713], - [0.007588, 0.006356, 0.044973], - [0.009426, 0.008022, 0.052844], - [0.011465, 0.009828, 0.06075], - [0.013708, 0.011771, 0.068667], - [0.016156, 0.01384, 0.076603], - [0.018815, 0.016026, 0.084584], - [0.021692, 0.01832, 0.09261], - [0.024792, 0.020715, 0.100676], - [0.028123, 0.023201, 0.108787], - [0.031696, 0.025765, 0.116965], - [0.03552, 0.028397, 0.125209], - [0.039608, 0.03109, 0.133515], - [0.04383, 0.03383, 0.141886], - [0.048062, 0.036607, 0.150327], - [0.05232, 0.039407, 0.158841], - [0.056615, 0.04216, 0.167446], - [0.060949, 0.044794, 0.176129], - [0.06533, 0.047318, 0.184892], - [0.069764, 0.049726, 0.193735], - [0.074257, 0.052017, 0.20266], - [0.078815, 0.054184, 0.211667], - [0.083446, 0.056225, 0.220755], - [0.088155, 0.058133, 0.229922], - [0.092949, 0.059904, 0.239164], - [0.097833, 0.061531, 0.248477], - [0.102815, 0.06301, 0.257854], - [0.107899, 0.064335, 0.267289], - [0.113094, 0.065492, 0.276784], - [0.118405, 0.066479, 0.286321], - [0.123833, 0.067295, 0.295879], - [0.12938, 0.067935, 0.305443], - [0.135053, 0.068391, 0.315], - [0.140858, 0.068654, 0.324538], - [0.146785, 0.068738, 0.334011], - [0.152839, 0.068637, 0.343404], - [0.159018, 0.068354, 0.352688], - [0.165308, 0.067911, 0.361816], - [0.171713, 0.067305, 0.370771], - [0.178212, 0.066576, 0.379497], - [0.184801, 0.065732, 0.387973], - [0.19146, 0.064818, 0.396152], - [0.198177, 0.063862, 0.404009], - [0.204935, 0.062907, 0.411514], - [0.211718, 0.061992, 0.418647], - [0.218512, 0.061158, 0.425392], - [0.225302, 0.060445, 0.431742], - [0.232077, 0.059889, 0.437695], - [0.238826, 0.059517, 0.443256], - [0.245543, 0.059352, 0.448436], - [0.25222, 0.059415, 0.453248], - [0.258857, 0.059706, 0.45771], - [0.265447, 0.060237, 0.46184], - [0.271994, 0.060994, 0.46566], - [0.278493, 0.061978, 0.46919], - [0.284951, 0.063168, 0.472451], - [0.291366, 0.064553, 0.475462], - [0.29774, 0.066117, 0.478243], - [0.304081, 0.067835, 0.480812], - [0.310382, 0.069702, 0.483186], - [0.316654, 0.07169, 0.48538], - [0.322899, 0.073782, 0.487408], - [0.329114, 0.075972, 0.489287], - [0.335308, 0.078236, 0.491024], - [0.341482, 0.080564, 0.492631], - [0.347636, 0.082946, 0.494121], - [0.353773, 0.085373, 0.495501], - [0.359898, 0.087831, 0.496778], - [0.366012, 0.090314, 0.49796], - [0.372116, 0.092816, 0.499053], - [0.378211, 0.095332, 0.500067], - [0.384299, 0.097855, 0.501002], - [0.390384, 0.100379, 0.501864], - [0.396467, 0.102902, 0.502658], - [0.402548, 0.10542, 0.503386], - [0.408629, 0.10793, 0.504052], - [0.414709, 0.110431, 0.504662], - [0.420791, 0.11292, 0.505215], - [0.426877, 0.115395, 0.505714], - [0.432967, 0.117855, 0.50616], - [0.439062, 0.120298, 0.506555], - [0.445163, 0.122724, 0.506901], - [0.451271, 0.125132, 0.507198], - [0.457386, 0.127522, 0.507448], - [0.463508, 0.129893, 0.507652], - [0.46964, 0.132245, 0.507809], - [0.47578, 0.134577, 0.507921], - [0.481929, 0.136891, 0.507989], - [0.488088, 0.139186, 0.508011], - [0.494258, 0.141462, 0.507988], - [0.500438, 0.143719, 0.50792], - [0.506629, 0.145958, 0.507806], - [0.512831, 0.148179, 0.507648], - [0.519045, 0.150383, 0.507443], - [0.52527, 0.152569, 0.507192], - [0.531507, 0.154739, 0.506895], - [0.537755, 0.156894, 0.506551], - [0.544015, 0.159033, 0.506159], - [0.550287, 0.161158, 0.505719], - [0.556571, 0.163269, 0.50523], - [0.562866, 0.165368, 0.504692], - [0.569172, 0.167454, 0.504105], - [0.57549, 0.16953, 0.503466], - [0.581819, 0.171596, 0.502777], - [0.588158, 0.173652, 0.502035], - [0.594508, 0.175701, 0.501241], - [0.600868, 0.177743, 0.500394], - [0.607238, 0.179779, 0.499492], - [0.613617, 0.181811, 0.498536], - [0.620005, 0.18384, 0.497524], - [0.626401, 0.185867, 0.496456], - [0.632805, 0.187893, 0.495332], - [0.639216, 0.189921, 0.49415], - [0.645633, 0.191952, 0.49291], - [0.652056, 0.193986, 0.491611], - [0.658483, 0.196027, 0.490253], - [0.664915, 0.198075, 0.488836], - [0.671349, 0.200133, 0.487358], - [0.677786, 0.202203, 0.485819], - [0.684224, 0.204286, 0.484219], - [0.690661, 0.206384, 0.482558], - [0.697098, 0.208501, 0.480835], - [0.703532, 0.210638, 0.479049], - [0.709962, 0.212797, 0.477201], - [0.716387, 0.214982, 0.47529], - [0.722805, 0.217194, 0.473316], - [0.729216, 0.219437, 0.471279], - [0.735616, 0.221713, 0.46918], - [0.742004, 0.224025, 0.467018], - [0.748378, 0.226377, 0.464794], - [0.754737, 0.228772, 0.462509], - [0.761077, 0.231214, 0.460162], - [0.767398, 0.233705, 0.457755], - [0.773695, 0.236249, 0.455289], - [0.779968, 0.238851, 0.452765], - [0.786212, 0.241514, 0.450184], - [0.792427, 0.244242, 0.447543], - [0.798608, 0.24704, 0.444848], - [0.804752, 0.249911, 0.442102], - [0.810855, 0.252861, 0.439305], - [0.816914, 0.255895, 0.436461], - [0.822926, 0.259016, 0.433573], - [0.828886, 0.262229, 0.430644], - [0.834791, 0.26554, 0.427671], - [0.840636, 0.268953, 0.424666], - [0.846416, 0.272473, 0.421631], - [0.852126, 0.276106, 0.418573], - [0.857763, 0.279857, 0.415496], - [0.86332, 0.283729, 0.412403], - [0.868793, 0.287728, 0.409303], - [0.874176, 0.291859, 0.406205], - [0.879464, 0.296125, 0.403118], - [0.884651, 0.30053, 0.400047], - [0.889731, 0.305079, 0.397002], - [0.8947, 0.309773, 0.393995], - [0.899552, 0.314616, 0.391037], - [0.904281, 0.31961, 0.388137], - [0.908884, 0.324755, 0.385308], - [0.913354, 0.330052, 0.382563], - [0.917689, 0.3355, 0.379915], - [0.921884, 0.341098, 0.377376], - [0.925937, 0.346844, 0.374959], - [0.929845, 0.352734, 0.372677], - [0.933606, 0.358764, 0.370541], - [0.937221, 0.364929, 0.368567], - [0.940687, 0.371224, 0.366762], - [0.944006, 0.377643, 0.365136], - [0.94718, 0.384178, 0.363701], - [0.95021, 0.39082, 0.362468], - [0.953099, 0.397563, 0.361438], - [0.955849, 0.4044, 0.360619], - [0.958464, 0.411324, 0.360014], - [0.960949, 0.418323, 0.35963], - [0.96331, 0.42539, 0.359469], - [0.965549, 0.432519, 0.359529], - [0.967671, 0.439703, 0.35981], - [0.96968, 0.446936, 0.360311], - [0.971582, 0.45421, 0.36103], - [0.973381, 0.46152, 0.361965], - [0.975082, 0.468861, 0.363111], - [0.97669, 0.476226, 0.364466], - [0.97821, 0.483612, 0.366025], - [0.979645, 0.491014, 0.367783], - [0.981, 0.498428, 0.369734], - [0.982279, 0.505851, 0.371874], - [0.983485, 0.51328, 0.374198], - [0.984622, 0.520713, 0.376698], - [0.985693, 0.528148, 0.379371], - [0.9867, 0.535582, 0.38221], - [0.987646, 0.543015, 0.38521], - [0.988533, 0.550446, 0.388365], - [0.989363, 0.557873, 0.391671], - [0.990138, 0.565296, 0.395122], - [0.990871, 0.572706, 0.398714], - [0.991558, 0.580107, 0.402441], - [0.992196, 0.587502, 0.406299], - [0.992785, 0.594891, 0.410283], - [0.993326, 0.602275, 0.41439], - [0.993834, 0.609644, 0.418613], - [0.994309, 0.616999, 0.42295], - [0.994738, 0.62435, 0.427397], - [0.995122, 0.631696, 0.431951], - [0.99548, 0.639027, 0.436607], - [0.99581, 0.646344, 0.441361], - [0.996096, 0.653659, 0.446213], - [0.996341, 0.660969, 0.45116], - [0.99658, 0.668256, 0.456192], - [0.996775, 0.675541, 0.461314], - [0.996925, 0.682828, 0.466526], - [0.997077, 0.690088, 0.471811], - [0.997186, 0.697349, 0.477182], - [0.997254, 0.704611, 0.482635], - [0.997325, 0.711848, 0.488154], - [0.997351, 0.719089, 0.493755], - [0.997351, 0.726324, 0.499428], - [0.997341, 0.733545, 0.505167], - [0.997285, 0.740772, 0.510983], - [0.997228, 0.747981, 0.516859], - [0.997138, 0.75519, 0.522806], - [0.997019, 0.762398, 0.528821], - [0.996898, 0.769591, 0.534892], - [0.996727, 0.776795, 0.541039], - [0.996571, 0.783977, 0.547233], - [0.996369, 0.791167, 0.553499], - [0.996162, 0.798348, 0.55982], - [0.995932, 0.805527, 0.566202], - [0.99568, 0.812706, 0.572645], - [0.995424, 0.819875, 0.57914], - [0.995131, 0.827052, 0.585701], - [0.994851, 0.834213, 0.592307], - [0.994524, 0.841387, 0.598983], - [0.994222, 0.84854, 0.605696], - [0.993866, 0.855711, 0.612482], - [0.993545, 0.862859, 0.619299], - [0.99317, 0.870024, 0.626189], - [0.992831, 0.877168, 0.633109], - [0.99244, 0.88433, 0.640099], - [0.992089, 0.89147, 0.647116], - [0.991688, 0.898627, 0.654202], - [0.991332, 0.905763, 0.661309], - [0.99093, 0.912915, 0.668481], - [0.99057, 0.920049, 0.675675], - [0.990175, 0.927196, 0.682926], - [0.989815, 0.934329, 0.690198], - [0.989434, 0.94147, 0.697519], - [0.989077, 0.948604, 0.704863], - [0.988717, 0.955742, 0.712242], - [0.988367, 0.962878, 0.719649], - [0.988033, 0.970012, 0.727077], - [0.987691, 0.977154, 0.734536], - [0.987387, 0.984288, 0.742002], - [0.987053, 0.991438, 0.749504], -]; - -export const colormap_inferno_data: Array<[number, number, number]> = [ - [0.001462, 0.000466, 0.013866], - [0.002267, 0.00127, 0.01857], - [0.003299, 0.002249, 0.024239], - [0.004547, 0.003392, 0.030909], - [0.006006, 0.004692, 0.038558], - [0.007676, 0.006136, 0.046836], - [0.009561, 0.007713, 0.055143], - [0.011663, 0.009417, 0.06346], - [0.013995, 0.011225, 0.071862], - [0.016561, 0.013136, 0.080282], - [0.019373, 0.015133, 0.088767], - [0.022447, 0.017199, 0.097327], - [0.025793, 0.019331, 0.10593], - [0.029432, 0.021503, 0.114621], - [0.033385, 0.023702, 0.123397], - [0.037668, 0.025921, 0.132232], - [0.042253, 0.028139, 0.141141], - [0.046915, 0.030324, 0.150164], - [0.051644, 0.032474, 0.159254], - [0.056449, 0.034569, 0.168414], - [0.06134, 0.03659, 0.177642], - [0.066331, 0.038504, 0.186962], - [0.071429, 0.040294, 0.196354], - [0.076637, 0.041905, 0.205799], - [0.081962, 0.043328, 0.215289], - [0.087411, 0.044556, 0.224813], - [0.09299, 0.045583, 0.234358], - [0.098702, 0.046402, 0.243904], - [0.104551, 0.047008, 0.25343], - [0.110536, 0.047399, 0.262912], - [0.116656, 0.047574, 0.272321], - [0.122908, 0.047536, 0.281624], - [0.129285, 0.047293, 0.290788], - [0.135778, 0.046856, 0.299776], - [0.142378, 0.046242, 0.308553], - [0.149073, 0.045468, 0.317085], - [0.15585, 0.044559, 0.325338], - [0.162689, 0.043554, 0.333277], - [0.169575, 0.042489, 0.340874], - [0.176493, 0.041402, 0.348111], - [0.183429, 0.040329, 0.354971], - [0.190367, 0.039309, 0.361447], - [0.197297, 0.0384, 0.367535], - [0.204209, 0.037632, 0.373238], - [0.211095, 0.03703, 0.378563], - [0.217949, 0.036615, 0.383522], - [0.224763, 0.036405, 0.388129], - [0.231538, 0.036405, 0.3924], - [0.238273, 0.036621, 0.396353], - [0.244967, 0.037055, 0.400007], - [0.25162, 0.037705, 0.403378], - [0.258234, 0.038571, 0.406485], - [0.26481, 0.039647, 0.409345], - [0.271347, 0.040922, 0.411976], - [0.27785, 0.042353, 0.414392], - [0.284321, 0.043933, 0.416608], - [0.290763, 0.045644, 0.418637], - [0.297178, 0.04747, 0.420491], - [0.303568, 0.049396, 0.422182], - [0.309935, 0.051407, 0.423721], - [0.316282, 0.05349, 0.425116], - [0.32261, 0.055634, 0.426377], - [0.328921, 0.057827, 0.427511], - [0.335217, 0.06006, 0.428524], - [0.3415, 0.062325, 0.429425], - [0.347771, 0.064616, 0.430217], - [0.354032, 0.066925, 0.430906], - [0.360284, 0.069247, 0.431497], - [0.366529, 0.071579, 0.431994], - [0.372768, 0.073915, 0.4324], - [0.379001, 0.076253, 0.432719], - [0.385228, 0.078591, 0.432955], - [0.391453, 0.080927, 0.433109], - [0.397674, 0.083257, 0.433183], - [0.403894, 0.08558, 0.433179], - [0.410113, 0.087896, 0.433098], - [0.416331, 0.090203, 0.432943], - [0.422549, 0.092501, 0.432714], - [0.428768, 0.09479, 0.432412], - [0.434987, 0.097069, 0.432039], - [0.441207, 0.099338, 0.431594], - [0.447428, 0.101597, 0.43108], - [0.453651, 0.103848, 0.430498], - [0.459875, 0.106089, 0.429846], - [0.4661, 0.108322, 0.429125], - [0.472328, 0.110547, 0.428334], - [0.478558, 0.112764, 0.427475], - [0.484789, 0.114974, 0.426548], - [0.491022, 0.117179, 0.425552], - [0.497257, 0.119379, 0.424488], - [0.503493, 0.121575, 0.423356], - [0.50973, 0.123769, 0.422156], - [0.515967, 0.12596, 0.420887], - [0.522206, 0.12815, 0.419549], - [0.528444, 0.130341, 0.418142], - [0.534683, 0.132534, 0.416667], - [0.54092, 0.134729, 0.415123], - [0.547157, 0.136929, 0.413511], - [0.553392, 0.139134, 0.411829], - [0.559624, 0.141346, 0.410078], - [0.565854, 0.143567, 0.408258], - [0.572081, 0.145797, 0.406369], - [0.578304, 0.148039, 0.404411], - [0.584521, 0.150294, 0.402385], - [0.590734, 0.152563, 0.40029], - [0.59694, 0.154848, 0.398125], - [0.603139, 0.157151, 0.395891], - [0.60933, 0.159474, 0.393589], - [0.615513, 0.161817, 0.391219], - [0.621685, 0.164184, 0.388781], - [0.627847, 0.166575, 0.386276], - [0.633998, 0.168992, 0.383704], - [0.640135, 0.171438, 0.381065], - [0.64626, 0.173914, 0.378359], - [0.652369, 0.176421, 0.375586], - [0.658463, 0.178962, 0.372748], - [0.66454, 0.181539, 0.369846], - [0.670599, 0.184153, 0.366879], - [0.676638, 0.186807, 0.363849], - [0.682656, 0.189501, 0.360757], - [0.688653, 0.192239, 0.357603], - [0.694627, 0.195021, 0.354388], - [0.700576, 0.197851, 0.351113], - [0.7065, 0.200728, 0.347777], - [0.712396, 0.203656, 0.344383], - [0.718264, 0.206636, 0.340931], - [0.724103, 0.20967, 0.337424], - [0.729909, 0.212759, 0.333861], - [0.735683, 0.215906, 0.330245], - [0.741423, 0.219112, 0.326576], - [0.747127, 0.222378, 0.322856], - [0.752794, 0.225706, 0.319085], - [0.758422, 0.229097, 0.315266], - [0.76401, 0.232554, 0.311399], - [0.769556, 0.236077, 0.307485], - [0.775059, 0.239667, 0.303526], - [0.780517, 0.243327, 0.299523], - [0.785929, 0.247056, 0.295477], - [0.791293, 0.250856, 0.29139], - [0.796607, 0.254728, 0.287264], - [0.801871, 0.258674, 0.283099], - [0.807082, 0.262692, 0.278898], - [0.812239, 0.266786, 0.274661], - [0.817341, 0.270954, 0.27039], - [0.822386, 0.275197, 0.266085], - [0.827372, 0.279517, 0.26175], - [0.832299, 0.283913, 0.257383], - [0.837165, 0.288385, 0.252988], - [0.841969, 0.292933, 0.248564], - [0.846709, 0.297559, 0.244113], - [0.851384, 0.30226, 0.239636], - [0.855992, 0.307038, 0.235133], - [0.860533, 0.311892, 0.230606], - [0.865006, 0.316822, 0.226055], - [0.869409, 0.321827, 0.221482], - [0.873741, 0.326906, 0.216886], - [0.878001, 0.33206, 0.212268], - [0.882188, 0.337287, 0.207628], - [0.886302, 0.342586, 0.202968], - [0.890341, 0.347957, 0.198286], - [0.894305, 0.353399, 0.193584], - [0.898192, 0.358911, 0.18886], - [0.902003, 0.364492, 0.184116], - [0.905735, 0.37014, 0.17935], - [0.90939, 0.375856, 0.174563], - [0.912966, 0.381636, 0.169755], - [0.916462, 0.387481, 0.164924], - [0.919879, 0.393389, 0.16007], - [0.923215, 0.399359, 0.155193], - [0.92647, 0.405389, 0.150292], - [0.929644, 0.411479, 0.145367], - [0.932737, 0.417627, 0.140417], - [0.935747, 0.423831, 0.13544], - [0.938675, 0.430091, 0.130438], - [0.941521, 0.436405, 0.125409], - [0.944285, 0.442772, 0.120354], - [0.946965, 0.449191, 0.115272], - [0.949562, 0.45566, 0.110164], - [0.952075, 0.462178, 0.105031], - [0.954506, 0.468744, 0.099874], - [0.956852, 0.475356, 0.094695], - [0.959114, 0.482014, 0.089499], - [0.961293, 0.488716, 0.084289], - [0.963387, 0.495462, 0.079073], - [0.965397, 0.502249, 0.073859], - [0.967322, 0.509078, 0.068659], - [0.969163, 0.515946, 0.063488], - [0.970919, 0.522853, 0.058367], - [0.97259, 0.529798, 0.053324], - [0.974176, 0.53678, 0.048392], - [0.975677, 0.543798, 0.043618], - [0.977092, 0.55085, 0.03905], - [0.978422, 0.557937, 0.034931], - [0.979666, 0.565057, 0.031409], - [0.980824, 0.572209, 0.028508], - [0.981895, 0.579392, 0.02625], - [0.982881, 0.586606, 0.024661], - [0.983779, 0.593849, 0.02377], - [0.984591, 0.601122, 0.023606], - [0.985315, 0.608422, 0.024202], - [0.985952, 0.61575, 0.025592], - [0.986502, 0.623105, 0.027814], - [0.986964, 0.630485, 0.030908], - [0.987337, 0.63789, 0.034916], - [0.987622, 0.64532, 0.039886], - [0.987819, 0.652773, 0.045581], - [0.987926, 0.66025, 0.05175], - [0.987945, 0.667748, 0.058329], - [0.987874, 0.675267, 0.065257], - [0.987714, 0.682807, 0.072489], - [0.987464, 0.690366, 0.07999], - [0.987124, 0.697944, 0.087731], - [0.986694, 0.70554, 0.095694], - [0.986175, 0.713153, 0.103863], - [0.985566, 0.720782, 0.112229], - [0.984865, 0.728427, 0.120785], - [0.984075, 0.736087, 0.129527], - [0.983196, 0.743758, 0.138453], - [0.982228, 0.751442, 0.147565], - [0.981173, 0.759135, 0.156863], - [0.980032, 0.766837, 0.166353], - [0.978806, 0.774545, 0.176037], - [0.977497, 0.782258, 0.185923], - [0.976108, 0.789974, 0.196018], - [0.974638, 0.797692, 0.206332], - [0.973088, 0.805409, 0.216877], - [0.971468, 0.813122, 0.227658], - [0.969783, 0.820825, 0.238686], - [0.968041, 0.828515, 0.249972], - [0.966243, 0.836191, 0.261534], - [0.964394, 0.843848, 0.273391], - [0.962517, 0.851476, 0.285546], - [0.960626, 0.859069, 0.29801], - [0.95872, 0.866624, 0.31082], - [0.956834, 0.874129, 0.323974], - [0.954997, 0.881569, 0.337475], - [0.953215, 0.888942, 0.351369], - [0.951546, 0.896226, 0.365627], - [0.950018, 0.903409, 0.380271], - [0.948683, 0.910473, 0.395289], - [0.947594, 0.917399, 0.410665], - [0.946809, 0.924168, 0.426373], - [0.946392, 0.930761, 0.442367], - [0.946403, 0.937159, 0.458592], - [0.946903, 0.943348, 0.47497], - [0.947937, 0.949318, 0.491426], - [0.949545, 0.955063, 0.50786], - [0.95174, 0.960587, 0.524203], - [0.954529, 0.965896, 0.540361], - [0.957896, 0.971003, 0.556275], - [0.961812, 0.975924, 0.571925], - [0.966249, 0.980678, 0.587206], - [0.971162, 0.985282, 0.602154], - [0.976511, 0.989753, 0.61676], - [0.982257, 0.994109, 0.631017], - [0.988362, 0.998364, 0.644924], -]; - -export const colormap_plasma_data: Array<[number, number, number]> = [ - [0.050383, 0.029803, 0.527975], - [0.063536, 0.028426, 0.533124], - [0.075353, 0.027206, 0.538007], - [0.086222, 0.026125, 0.542658], - [0.096379, 0.025165, 0.547103], - [0.10598, 0.024309, 0.551368], - [0.115124, 0.023556, 0.555468], - [0.123903, 0.022878, 0.559423], - [0.132381, 0.022258, 0.56325], - [0.140603, 0.021687, 0.566959], - [0.148607, 0.021154, 0.570562], - [0.156421, 0.020651, 0.574065], - [0.16407, 0.020171, 0.577478], - [0.171574, 0.019706, 0.580806], - [0.17895, 0.019252, 0.584054], - [0.186213, 0.018803, 0.587228], - [0.193374, 0.018354, 0.59033], - [0.200445, 0.017902, 0.593364], - [0.207435, 0.017442, 0.596333], - [0.21435, 0.016973, 0.599239], - [0.221197, 0.016497, 0.602083], - [0.227983, 0.016007, 0.604867], - [0.234715, 0.015502, 0.607592], - [0.241396, 0.014979, 0.610259], - [0.248032, 0.014439, 0.612868], - [0.254627, 0.013882, 0.615419], - [0.261183, 0.013308, 0.617911], - [0.267703, 0.012716, 0.620346], - [0.274191, 0.012109, 0.622722], - [0.280648, 0.011488, 0.625038], - [0.287076, 0.010855, 0.627295], - [0.293478, 0.010213, 0.62949], - [0.299855, 0.009561, 0.631624], - [0.30621, 0.008902, 0.633694], - [0.312543, 0.008239, 0.6357], - [0.318856, 0.007576, 0.63764], - [0.32515, 0.006915, 0.639512], - [0.331426, 0.006261, 0.641316], - [0.337683, 0.005618, 0.643049], - [0.343925, 0.004991, 0.64471], - [0.35015, 0.004382, 0.646298], - [0.356359, 0.003798, 0.64781], - [0.362553, 0.003243, 0.649245], - [0.368733, 0.002724, 0.650601], - [0.374897, 0.002245, 0.651876], - [0.381047, 0.001814, 0.653068], - [0.387183, 0.001434, 0.654177], - [0.393304, 0.001114, 0.655199], - [0.399411, 0.000859, 0.656133], - [0.405503, 0.000678, 0.656977], - [0.41158, 0.000577, 0.65773], - [0.417642, 0.000564, 0.65839], - [0.423689, 0.000646, 0.658956], - [0.429719, 0.000831, 0.659425], - [0.435734, 0.001127, 0.659797], - [0.441732, 0.00154, 0.660069], - [0.447714, 0.00208, 0.66024], - [0.453677, 0.002755, 0.66031], - [0.459623, 0.003574, 0.660277], - [0.46555, 0.004545, 0.660139], - [0.471457, 0.005678, 0.659897], - [0.477344, 0.00698, 0.659549], - [0.48321, 0.00846, 0.659095], - [0.489055, 0.010127, 0.658534], - [0.494877, 0.01199, 0.657865], - [0.500678, 0.014055, 0.657088], - [0.506454, 0.016333, 0.656202], - [0.512206, 0.018833, 0.655209], - [0.517933, 0.021563, 0.654109], - [0.523633, 0.024532, 0.652901], - [0.529306, 0.027747, 0.651586], - [0.534952, 0.031217, 0.650165], - [0.54057, 0.03495, 0.64864], - [0.546157, 0.038954, 0.64701], - [0.551715, 0.043136, 0.645277], - [0.557243, 0.047331, 0.643443], - [0.562738, 0.051545, 0.641509], - [0.568201, 0.055778, 0.639477], - [0.573632, 0.060028, 0.637349], - [0.579029, 0.064296, 0.635126], - [0.584391, 0.068579, 0.632812], - [0.589719, 0.072878, 0.630408], - [0.595011, 0.07719, 0.627917], - [0.600266, 0.081516, 0.625342], - [0.605485, 0.085854, 0.622686], - [0.610667, 0.090204, 0.619951], - [0.615812, 0.094564, 0.61714], - [0.620919, 0.098934, 0.614257], - [0.625987, 0.103312, 0.611305], - [0.631017, 0.107699, 0.608287], - [0.636008, 0.112092, 0.605205], - [0.640959, 0.116492, 0.602065], - [0.645872, 0.120898, 0.598867], - [0.650746, 0.125309, 0.595617], - [0.65558, 0.129725, 0.592317], - [0.660374, 0.134144, 0.588971], - [0.665129, 0.138566, 0.585582], - [0.669845, 0.142992, 0.582154], - [0.674522, 0.147419, 0.578688], - [0.67916, 0.151848, 0.575189], - [0.683758, 0.156278, 0.57166], - [0.688318, 0.160709, 0.568103], - [0.69284, 0.165141, 0.564522], - [0.697324, 0.169573, 0.560919], - [0.701769, 0.174005, 0.557296], - [0.706178, 0.178437, 0.553657], - [0.710549, 0.182868, 0.550004], - [0.714883, 0.187299, 0.546338], - [0.719181, 0.191729, 0.542663], - [0.723444, 0.196158, 0.538981], - [0.72767, 0.200586, 0.535293], - [0.731862, 0.205013, 0.531601], - [0.736019, 0.209439, 0.527908], - [0.740143, 0.213864, 0.524216], - [0.744232, 0.218288, 0.520524], - [0.748289, 0.222711, 0.516834], - [0.752312, 0.227133, 0.513149], - [0.756304, 0.231555, 0.509468], - [0.760264, 0.235976, 0.505794], - [0.764193, 0.240396, 0.502126], - [0.76809, 0.244817, 0.498465], - [0.771958, 0.249237, 0.494813], - [0.775796, 0.253658, 0.491171], - [0.779604, 0.258078, 0.487539], - [0.783383, 0.2625, 0.483918], - [0.787133, 0.266922, 0.480307], - [0.790855, 0.271345, 0.476706], - [0.794549, 0.27577, 0.473117], - [0.798216, 0.280197, 0.469538], - [0.801855, 0.284626, 0.465971], - [0.805467, 0.289057, 0.462415], - [0.809052, 0.293491, 0.45887], - [0.812612, 0.297928, 0.455338], - [0.816144, 0.302368, 0.451816], - [0.819651, 0.306812, 0.448306], - [0.823132, 0.311261, 0.444806], - [0.826588, 0.315714, 0.441316], - [0.830018, 0.320172, 0.437836], - [0.833422, 0.324635, 0.434366], - [0.836801, 0.329105, 0.430905], - [0.840155, 0.33358, 0.427455], - [0.843484, 0.338062, 0.424013], - [0.846788, 0.342551, 0.420579], - [0.850066, 0.347048, 0.417153], - [0.853319, 0.351553, 0.413734], - [0.856547, 0.356066, 0.410322], - [0.85975, 0.360588, 0.406917], - [0.862927, 0.365119, 0.403519], - [0.866078, 0.36966, 0.400126], - [0.869203, 0.374212, 0.396738], - [0.872303, 0.378774, 0.393355], - [0.875376, 0.383347, 0.389976], - [0.878423, 0.387932, 0.3866], - [0.881443, 0.392529, 0.383229], - [0.884436, 0.397139, 0.37986], - [0.887402, 0.401762, 0.376494], - [0.89034, 0.406398, 0.37313], - [0.89325, 0.411048, 0.369768], - [0.896131, 0.415712, 0.366407], - [0.898984, 0.420392, 0.363047], - [0.901807, 0.425087, 0.359688], - [0.904601, 0.429797, 0.356329], - [0.907365, 0.434524, 0.35297], - [0.910098, 0.439268, 0.34961], - [0.9128, 0.444029, 0.346251], - [0.915471, 0.448807, 0.34289], - [0.918109, 0.453603, 0.339529], - [0.920714, 0.458417, 0.336166], - [0.923287, 0.463251, 0.332801], - [0.925825, 0.468103, 0.329435], - [0.928329, 0.472975, 0.326067], - [0.930798, 0.477867, 0.322697], - [0.933232, 0.48278, 0.319325], - [0.93563, 0.487712, 0.315952], - [0.93799, 0.492667, 0.312575], - [0.940313, 0.497642, 0.309197], - [0.942598, 0.502639, 0.305816], - [0.944844, 0.507658, 0.302433], - [0.947051, 0.512699, 0.299049], - [0.949217, 0.517763, 0.295662], - [0.951344, 0.52285, 0.292275], - [0.953428, 0.52796, 0.288883], - [0.95547, 0.533093, 0.28549], - [0.957469, 0.53825, 0.282096], - [0.959424, 0.543431, 0.278701], - [0.961336, 0.548636, 0.275305], - [0.963203, 0.553865, 0.271909], - [0.965024, 0.559118, 0.268513], - [0.966798, 0.564396, 0.265118], - [0.968526, 0.5697, 0.261721], - [0.970205, 0.575028, 0.258325], - [0.971835, 0.580382, 0.254931], - [0.973416, 0.585761, 0.25154], - [0.974947, 0.591165, 0.248151], - [0.976428, 0.596595, 0.244767], - [0.977856, 0.602051, 0.241387], - [0.979233, 0.607532, 0.238013], - [0.980556, 0.613039, 0.234646], - [0.981826, 0.618572, 0.231287], - [0.983041, 0.624131, 0.227937], - [0.984199, 0.629718, 0.224595], - [0.985301, 0.63533, 0.221265], - [0.986345, 0.640969, 0.217948], - [0.987332, 0.646633, 0.214648], - [0.98826, 0.652325, 0.211364], - [0.989128, 0.658043, 0.2081], - [0.989935, 0.663787, 0.204859], - [0.990681, 0.669558, 0.201642], - [0.991365, 0.675355, 0.198453], - [0.991985, 0.681179, 0.195295], - [0.992541, 0.68703, 0.19217], - [0.993032, 0.692907, 0.189084], - [0.993456, 0.69881, 0.186041], - [0.993814, 0.704741, 0.183043], - [0.994103, 0.710698, 0.180097], - [0.994324, 0.716681, 0.177208], - [0.994474, 0.722691, 0.174381], - [0.994553, 0.728728, 0.171622], - [0.994561, 0.734791, 0.168938], - [0.994495, 0.74088, 0.166335], - [0.994355, 0.746995, 0.163821], - [0.994141, 0.753137, 0.161404], - [0.993851, 0.759304, 0.159092], - [0.993482, 0.765499, 0.156891], - [0.993033, 0.77172, 0.154808], - [0.992505, 0.777967, 0.152855], - [0.991897, 0.784239, 0.151042], - [0.991209, 0.790537, 0.149377], - [0.990439, 0.796859, 0.14787], - [0.989587, 0.803205, 0.146529], - [0.988648, 0.809579, 0.145357], - [0.987621, 0.815978, 0.144363], - [0.986509, 0.822401, 0.143557], - [0.985314, 0.828846, 0.142945], - [0.984031, 0.835315, 0.142528], - [0.982653, 0.841812, 0.142303], - [0.98119, 0.848329, 0.142279], - [0.979644, 0.854866, 0.142453], - [0.977995, 0.861432, 0.142808], - [0.976265, 0.868016, 0.143351], - [0.974443, 0.874622, 0.144061], - [0.97253, 0.88125, 0.144923], - [0.970533, 0.887896, 0.145919], - [0.968443, 0.894564, 0.147014], - [0.966271, 0.901249, 0.14818], - [0.964021, 0.90795, 0.14937], - [0.961681, 0.914672, 0.15052], - [0.959276, 0.921407, 0.151566], - [0.956808, 0.928152, 0.152409], - [0.954287, 0.934908, 0.152921], - [0.951726, 0.941671, 0.152925], - [0.949151, 0.948435, 0.152178], - [0.946602, 0.95519, 0.150328], - [0.944152, 0.961916, 0.146861], - [0.941896, 0.96859, 0.140956], - [0.940015, 0.975158, 0.131326], -]; - -export const colormap_viridis_data: Array<[number, number, number]> = [ - [0.267004, 0.004874, 0.329415], - [0.26851, 0.009605, 0.335427], - [0.269944, 0.014625, 0.341379], - [0.271305, 0.019942, 0.347269], - [0.272594, 0.025563, 0.353093], - [0.273809, 0.031497, 0.358853], - [0.274952, 0.037752, 0.364543], - [0.276022, 0.044167, 0.370164], - [0.277018, 0.050344, 0.375715], - [0.277941, 0.056324, 0.381191], - [0.278791, 0.062145, 0.386592], - [0.279566, 0.067836, 0.391917], - [0.280267, 0.073417, 0.397163], - [0.280894, 0.078907, 0.402329], - [0.281446, 0.08432, 0.407414], - [0.281924, 0.089666, 0.412415], - [0.282327, 0.094955, 0.417331], - [0.282656, 0.100196, 0.42216], - [0.28291, 0.105393, 0.426902], - [0.283091, 0.110553, 0.431554], - [0.283197, 0.11568, 0.436115], - [0.283229, 0.120777, 0.440584], - [0.283187, 0.125848, 0.44496], - [0.283072, 0.130895, 0.449241], - [0.282884, 0.13592, 0.453427], - [0.282623, 0.140926, 0.457517], - [0.28229, 0.145912, 0.46151], - [0.281887, 0.150881, 0.465405], - [0.281412, 0.155834, 0.469201], - [0.280868, 0.160771, 0.472899], - [0.280255, 0.165693, 0.476498], - [0.279574, 0.170599, 0.479997], - [0.278826, 0.17549, 0.483397], - [0.278012, 0.180367, 0.486697], - [0.277134, 0.185228, 0.489898], - [0.276194, 0.190074, 0.493001], - [0.275191, 0.194905, 0.496005], - [0.274128, 0.199721, 0.498911], - [0.273006, 0.20452, 0.501721], - [0.271828, 0.209303, 0.504434], - [0.270595, 0.214069, 0.507052], - [0.269308, 0.218818, 0.509577], - [0.267968, 0.223549, 0.512008], - [0.26658, 0.228262, 0.514349], - [0.265145, 0.232956, 0.516599], - [0.263663, 0.237631, 0.518762], - [0.262138, 0.242286, 0.520837], - [0.260571, 0.246922, 0.522828], - [0.258965, 0.251537, 0.524736], - [0.257322, 0.25613, 0.526563], - [0.255645, 0.260703, 0.528312], - [0.253935, 0.265254, 0.529983], - [0.252194, 0.269783, 0.531579], - [0.250425, 0.27429, 0.533103], - [0.248629, 0.278775, 0.534556], - [0.246811, 0.283237, 0.535941], - [0.244972, 0.287675, 0.53726], - [0.243113, 0.292092, 0.538516], - [0.241237, 0.296485, 0.539709], - [0.239346, 0.300855, 0.540844], - [0.237441, 0.305202, 0.541921], - [0.235526, 0.309527, 0.542944], - [0.233603, 0.313828, 0.543914], - [0.231674, 0.318106, 0.544834], - [0.229739, 0.322361, 0.545706], - [0.227802, 0.326594, 0.546532], - [0.225863, 0.330805, 0.547314], - [0.223925, 0.334994, 0.548053], - [0.221989, 0.339161, 0.548752], - [0.220057, 0.343307, 0.549413], - [0.21813, 0.347432, 0.550038], - [0.21621, 0.351535, 0.550627], - [0.214298, 0.355619, 0.551184], - [0.212395, 0.359683, 0.55171], - [0.210503, 0.363727, 0.552206], - [0.208623, 0.367752, 0.552675], - [0.206756, 0.371758, 0.553117], - [0.204903, 0.375746, 0.553533], - [0.203063, 0.379716, 0.553925], - [0.201239, 0.38367, 0.554294], - [0.19943, 0.387607, 0.554642], - [0.197636, 0.391528, 0.554969], - [0.19586, 0.395433, 0.555276], - [0.1941, 0.399323, 0.555565], - [0.192357, 0.403199, 0.555836], - [0.190631, 0.407061, 0.556089], - [0.188923, 0.41091, 0.556326], - [0.187231, 0.414746, 0.556547], - [0.185556, 0.41857, 0.556753], - [0.183898, 0.422383, 0.556944], - [0.182256, 0.426184, 0.55712], - [0.180629, 0.429975, 0.557282], - [0.179019, 0.433756, 0.55743], - [0.177423, 0.437527, 0.557565], - [0.175841, 0.44129, 0.557685], - [0.174274, 0.445044, 0.557792], - [0.172719, 0.448791, 0.557885], - [0.171176, 0.45253, 0.557965], - [0.169646, 0.456262, 0.55803], - [0.168126, 0.459988, 0.558082], - [0.166617, 0.463708, 0.558119], - [0.165117, 0.467423, 0.558141], - [0.163625, 0.471133, 0.558148], - [0.162142, 0.474838, 0.55814], - [0.160665, 0.47854, 0.558115], - [0.159194, 0.482237, 0.558073], - [0.157729, 0.485932, 0.558013], - [0.15627, 0.489624, 0.557936], - [0.154815, 0.493313, 0.55784], - [0.153364, 0.497, 0.557724], - [0.151918, 0.500685, 0.557587], - [0.150476, 0.504369, 0.55743], - [0.149039, 0.508051, 0.55725], - [0.147607, 0.511733, 0.557049], - [0.14618, 0.515413, 0.556823], - [0.144759, 0.519093, 0.556572], - [0.143343, 0.522773, 0.556295], - [0.141935, 0.526453, 0.555991], - [0.140536, 0.530132, 0.555659], - [0.139147, 0.533812, 0.555298], - [0.13777, 0.537492, 0.554906], - [0.136408, 0.541173, 0.554483], - [0.135066, 0.544853, 0.554029], - [0.133743, 0.548535, 0.553541], - [0.132444, 0.552216, 0.553018], - [0.131172, 0.555899, 0.552459], - [0.129933, 0.559582, 0.551864], - [0.128729, 0.563265, 0.551229], - [0.127568, 0.566949, 0.550556], - [0.126453, 0.570633, 0.549841], - [0.125394, 0.574318, 0.549086], - [0.124395, 0.578002, 0.548287], - [0.123463, 0.581687, 0.547445], - [0.122606, 0.585371, 0.546557], - [0.121831, 0.589055, 0.545623], - [0.121148, 0.592739, 0.544641], - [0.120565, 0.596422, 0.543611], - [0.120092, 0.600104, 0.54253], - [0.119738, 0.603785, 0.5414], - [0.119512, 0.607464, 0.540218], - [0.119423, 0.611141, 0.538982], - [0.119483, 0.614817, 0.537692], - [0.119699, 0.61849, 0.536347], - [0.120081, 0.622161, 0.534946], - [0.120638, 0.625828, 0.533488], - [0.12138, 0.629492, 0.531973], - [0.122312, 0.633153, 0.530398], - [0.123444, 0.636809, 0.528763], - [0.12478, 0.640461, 0.527068], - [0.126326, 0.644107, 0.525311], - [0.128087, 0.647749, 0.523491], - [0.130067, 0.651384, 0.521608], - [0.132268, 0.655014, 0.519661], - [0.134692, 0.658636, 0.517649], - [0.137339, 0.662252, 0.515571], - [0.14021, 0.665859, 0.513427], - [0.143303, 0.669459, 0.511215], - [0.146616, 0.67305, 0.508936], - [0.150148, 0.676631, 0.506589], - [0.153894, 0.680203, 0.504172], - [0.157851, 0.683765, 0.501686], - [0.162016, 0.687316, 0.499129], - [0.166383, 0.690856, 0.496502], - [0.170948, 0.694384, 0.493803], - [0.175707, 0.6979, 0.491033], - [0.180653, 0.701402, 0.488189], - [0.185783, 0.704891, 0.485273], - [0.19109, 0.708366, 0.482284], - [0.196571, 0.711827, 0.479221], - [0.202219, 0.715272, 0.476084], - [0.20803, 0.718701, 0.472873], - [0.214, 0.722114, 0.469588], - [0.220124, 0.725509, 0.466226], - [0.226397, 0.728888, 0.462789], - [0.232815, 0.732247, 0.459277], - [0.239374, 0.735588, 0.455688], - [0.24607, 0.73891, 0.452024], - [0.252899, 0.742211, 0.448284], - [0.259857, 0.745492, 0.444467], - [0.266941, 0.748751, 0.440573], - [0.274149, 0.751988, 0.436601], - [0.281477, 0.755203, 0.432552], - [0.288921, 0.758394, 0.428426], - [0.296479, 0.761561, 0.424223], - [0.304148, 0.764704, 0.419943], - [0.311925, 0.767822, 0.415586], - [0.319809, 0.770914, 0.411152], - [0.327796, 0.77398, 0.40664], - [0.335885, 0.777018, 0.402049], - [0.344074, 0.780029, 0.397381], - [0.35236, 0.783011, 0.392636], - [0.360741, 0.785964, 0.387814], - [0.369214, 0.788888, 0.382914], - [0.377779, 0.791781, 0.377939], - [0.386433, 0.794644, 0.372886], - [0.395174, 0.797475, 0.367757], - [0.404001, 0.800275, 0.362552], - [0.412913, 0.803041, 0.357269], - [0.421908, 0.805774, 0.35191], - [0.430983, 0.808473, 0.346476], - [0.440137, 0.811138, 0.340967], - [0.449368, 0.813768, 0.335384], - [0.458674, 0.816363, 0.329727], - [0.468053, 0.818921, 0.323998], - [0.477504, 0.821444, 0.318195], - [0.487026, 0.823929, 0.312321], - [0.496615, 0.826376, 0.306377], - [0.506271, 0.828786, 0.300362], - [0.515992, 0.831158, 0.294279], - [0.525776, 0.833491, 0.288127], - [0.535621, 0.835785, 0.281908], - [0.545524, 0.838039, 0.275626], - [0.555484, 0.840254, 0.269281], - [0.565498, 0.84243, 0.262877], - [0.575563, 0.844566, 0.256415], - [0.585678, 0.846661, 0.249897], - [0.595839, 0.848717, 0.243329], - [0.606045, 0.850733, 0.236712], - [0.616293, 0.852709, 0.230052], - [0.626579, 0.854645, 0.223353], - [0.636902, 0.856542, 0.21662], - [0.647257, 0.8584, 0.209861], - [0.657642, 0.860219, 0.203082], - [0.668054, 0.861999, 0.196293], - [0.678489, 0.863742, 0.189503], - [0.688944, 0.865448, 0.182725], - [0.699415, 0.867117, 0.175971], - [0.709898, 0.868751, 0.169257], - [0.720391, 0.87035, 0.162603], - [0.730889, 0.871916, 0.156029], - [0.741388, 0.873449, 0.149561], - [0.751884, 0.874951, 0.143228], - [0.762373, 0.876424, 0.137064], - [0.772852, 0.877868, 0.131109], - [0.783315, 0.879285, 0.125405], - [0.79376, 0.880678, 0.120005], - [0.804182, 0.882046, 0.114965], - [0.814576, 0.883393, 0.110347], - [0.82494, 0.88472, 0.106217], - [0.83527, 0.886029, 0.102646], - [0.845561, 0.887322, 0.099702], - [0.85581, 0.888601, 0.097452], - [0.866013, 0.889868, 0.095953], - [0.876168, 0.891125, 0.09525], - [0.886271, 0.892374, 0.095374], - [0.89632, 0.893616, 0.096335], - [0.906311, 0.894855, 0.098125], - [0.916242, 0.896091, 0.100717], - [0.926106, 0.89733, 0.104071], - [0.935904, 0.89857, 0.108131], - [0.945636, 0.899815, 0.112838], - [0.9553, 0.901065, 0.118128], - [0.964894, 0.902323, 0.123941], - [0.974417, 0.90359, 0.130215], - [0.983868, 0.904867, 0.136897], - [0.993248, 0.906157, 0.143936], -]; diff --git a/projects/wave-core/src/lib/colors/colormaps/scientific-colormaps/scientific-colormap.license b/projects/wave-core/src/lib/colors/colormaps/scientific-colormaps/scientific-colormap.license deleted file mode 100644 index cb10f7b8..00000000 --- a/projects/wave-core/src/lib/colors/colormaps/scientific-colormaps/scientific-colormap.license +++ /dev/null @@ -1,21 +0,0 @@ -The Scientific Colour Maps are licensed under a MIT License - -Copyright (c) 2020, Fabio Crameri - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -files (the ”Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED ”AS IS”, WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE diff --git a/projects/wave-core/src/lib/colors/colormaps/scientific-colormaps/scientific-colormaps.ts b/projects/wave-core/src/lib/colors/colormaps/scientific-colormaps/scientific-colormaps.ts deleted file mode 100644 index a26d8b62..00000000 --- a/projects/wave-core/src/lib/colors/colormaps/scientific-colormaps/scientific-colormaps.ts +++ /dev/null @@ -1,7328 +0,0 @@ -/** - * The colormaps in this file are derived from 'The Scientific Colour Maps' by Fabio Crameri: - * @See(http://www.fabiocrameri.ch/colourmaps.php) - * Crameri, F. (2018). Scientific colour-maps. Zenodo. - * Crameri, F. (2018), Geodynamic diagnostics, scientific visualisation and StagLab 3.0, - * Geosci. Model Dev., 11, 2541-2562, doi:10.5194/gmd-11-2541-2018 - * - * See 'The Scientific Colour Maps' MIT license and copyright in scientific-colormaps.license - */ - -/** - * The color map names. - */ -export type ScientificColormapName = - | 'ARCON' - | 'BAMAKO' - | 'BATLOW' - | 'BERLIN' - | 'BILBAO' - | 'BROC' - | 'BROCO' - | 'BUDA' - | 'CORC' - | 'CORCO' - | 'DAVOS' - | 'DEVON' - | 'GRAYC' - | 'HAWAII' - | 'IMOLA' - | 'LAJOLLA' - | 'LAPAZ' - | 'LISBON' - | 'NUUK' - | 'OLERON' - | 'OSLO' - | 'ROMA' - | 'ROMAO' - | 'TOFINO' - | 'TOKYO' - | 'TURKU' - | 'VIK' - | 'VIKO'; - -/** - * The list of available color map names. - */ -export const SCIENTIFIC_COLORMAP_NAMES: Array = [ - 'ARCON', - 'BAMAKO', - 'BATLOW', - 'BERLIN', - 'BILBAO', - 'BROC', - 'BROCO', - 'BUDA', - 'CORC', - 'CORCO', - 'DAVOS', - 'DEVON', - 'GRAYC', - 'HAWAII', - 'IMOLA', - 'LAJOLLA', - 'LAPAZ', - 'LISBON', - 'NUUK', - 'OLERON', - 'OSLO', - 'ROMA', - 'ROMAO', - 'TOFINO', - 'TOKYO', - 'TURKU', - 'VIK', - 'VIKO', -]; - -export const colormap_batlow_data: Array<[number, number, number]> = [ - [0.0051932, 0.098238, 0.34984], - [0.0090652, 0.10449, 0.35093], - [0.012963, 0.11078, 0.35199], - [0.01653, 0.11691, 0.35307], - [0.019936, 0.12298, 0.35412], - [0.023189, 0.12904, 0.35518], - [0.026291, 0.13504, 0.35621], - [0.029245, 0.14096, 0.35724], - [0.032053, 0.14677, 0.35824], - [0.034853, 0.15256, 0.35923], - [0.037449, 0.15831, 0.36022], - [0.039845, 0.16398, 0.36119], - [0.042104, 0.16956, 0.36215], - [0.044069, 0.17505, 0.36308], - [0.045905, 0.18046, 0.36401], - [0.047665, 0.18584, 0.36491], - [0.049378, 0.19108, 0.36581], - [0.050795, 0.19627, 0.36668], - [0.052164, 0.20132, 0.36752], - [0.053471, 0.20636, 0.36837], - [0.054721, 0.21123, 0.36918], - [0.055928, 0.21605, 0.36997], - [0.057033, 0.22075, 0.37075], - [0.058032, 0.22534, 0.37151], - [0.059164, 0.22984, 0.37225], - [0.060167, 0.2343, 0.37298], - [0.061052, 0.23862, 0.37369], - [0.06206, 0.24289, 0.37439], - [0.063071, 0.24709, 0.37505], - [0.063982, 0.25121, 0.37571], - [0.064936, 0.25526, 0.37636], - [0.065903, 0.25926, 0.37699], - [0.066899, 0.26319, 0.37759], - [0.067921, 0.26706, 0.37819], - [0.069002, 0.27092, 0.37877], - [0.070001, 0.27471, 0.37934], - [0.071115, 0.2785, 0.37989], - [0.072192, 0.28225, 0.38043], - [0.07344, 0.28594, 0.38096], - [0.074595, 0.28965, 0.38145], - [0.075833, 0.29332, 0.38192], - [0.077136, 0.297, 0.38238], - [0.078517, 0.30062, 0.38281], - [0.079984, 0.30425, 0.38322], - [0.081553, 0.30786, 0.3836], - [0.083082, 0.31146, 0.38394], - [0.084778, 0.31504, 0.38424], - [0.086503, 0.31862, 0.38451], - [0.088353, 0.32217, 0.38473], - [0.090281, 0.32569, 0.38491], - [0.092304, 0.32922, 0.38504], - [0.094462, 0.33271, 0.38512], - [0.096618, 0.33616, 0.38513], - [0.099015, 0.33962, 0.38509], - [0.10148, 0.34304, 0.38498], - [0.10408, 0.34641, 0.3848], - [0.10684, 0.34977, 0.38455], - [0.1097, 0.3531, 0.38422], - [0.11265, 0.35639, 0.38381], - [0.11575, 0.35964, 0.38331], - [0.11899, 0.36285, 0.38271], - [0.12232, 0.36603, 0.38203], - [0.12589, 0.36916, 0.38126], - [0.12952, 0.37224, 0.38038], - [0.1333, 0.37528, 0.3794], - [0.13721, 0.37828, 0.37831], - [0.14126, 0.38124, 0.37713], - [0.14543, 0.38413, 0.37584], - [0.14971, 0.38698, 0.37445], - [0.15407, 0.38978, 0.37293], - [0.15862, 0.39253, 0.37132], - [0.16325, 0.39524, 0.36961], - [0.16795, 0.39789, 0.36778], - [0.17279, 0.4005, 0.36587], - [0.17775, 0.40304, 0.36383], - [0.18273, 0.40555, 0.36171], - [0.18789, 0.408, 0.35948], - [0.19305, 0.41043, 0.35718], - [0.19831, 0.4128, 0.35477], - [0.20368, 0.41512, 0.35225], - [0.20908, 0.41741, 0.34968], - [0.21455, 0.41966, 0.34702], - [0.22011, 0.42186, 0.34426], - [0.22571, 0.42405, 0.34146], - [0.23136, 0.4262, 0.33857], - [0.23707, 0.42832, 0.33563], - [0.24279, 0.43042, 0.33263], - [0.24862, 0.43249, 0.32957], - [0.25445, 0.43453, 0.32643], - [0.26032, 0.43656, 0.32329], - [0.26624, 0.43856, 0.32009], - [0.27217, 0.44054, 0.31683], - [0.27817, 0.44252, 0.31355], - [0.28417, 0.44448, 0.31024], - [0.29021, 0.44642, 0.30689], - [0.29629, 0.44836, 0.30351], - [0.30238, 0.45028, 0.30012], - [0.30852, 0.4522, 0.29672], - [0.31465, 0.45411, 0.29328], - [0.32083, 0.45601, 0.28984], - [0.32701, 0.4579, 0.28638], - [0.33323, 0.45979, 0.28294], - [0.33947, 0.46168, 0.27947], - [0.3457, 0.46356, 0.276], - [0.35198, 0.46544, 0.27249], - [0.35828, 0.46733, 0.26904], - [0.36459, 0.46921, 0.26554], - [0.37092, 0.47109, 0.26206], - [0.37729, 0.47295, 0.25859], - [0.38368, 0.47484, 0.25513], - [0.39007, 0.47671, 0.25166], - [0.3965, 0.47859, 0.24821], - [0.40297, 0.48047, 0.24473], - [0.40945, 0.48235, 0.24131], - [0.41597, 0.48423, 0.23789], - [0.42251, 0.48611, 0.23449], - [0.42909, 0.48801, 0.2311], - [0.43571, 0.48989, 0.22773], - [0.44237, 0.4918, 0.22435], - [0.44905, 0.49368, 0.22107], - [0.45577, 0.49558, 0.21777], - [0.46254, 0.4975, 0.21452], - [0.46937, 0.49939, 0.21132], - [0.47622, 0.50131, 0.20815], - [0.48312, 0.50322, 0.20504], - [0.49008, 0.50514, 0.20198], - [0.49709, 0.50706, 0.19899], - [0.50415, 0.50898, 0.19612], - [0.51125, 0.5109, 0.1933], - [0.51842, 0.51282, 0.19057], - [0.52564, 0.51475, 0.18799], - [0.53291, 0.51666, 0.1855], - [0.54023, 0.51858, 0.1831], - [0.5476, 0.52049, 0.18088], - [0.55502, 0.52239, 0.17885], - [0.56251, 0.52429, 0.17696], - [0.57002, 0.52619, 0.17527], - [0.57758, 0.52806, 0.17377], - [0.5852, 0.52993, 0.17249], - [0.59285, 0.53178, 0.17145], - [0.60052, 0.5336, 0.17065], - [0.60824, 0.53542, 0.1701], - [0.61597, 0.53723, 0.16983], - [0.62374, 0.539, 0.16981], - [0.63151, 0.54075, 0.17007], - [0.6393, 0.54248, 0.17062], - [0.6471, 0.54418, 0.17146], - [0.65489, 0.54586, 0.1726], - [0.66269, 0.5475, 0.17404], - [0.67048, 0.54913, 0.17575], - [0.67824, 0.55071, 0.1778], - [0.686, 0.55227, 0.18006], - [0.69372, 0.5538, 0.18261], - [0.70142, 0.55529, 0.18548], - [0.7091, 0.55677, 0.18855], - [0.71673, 0.5582, 0.19185], - [0.72432, 0.55963, 0.19541], - [0.73188, 0.56101, 0.19917], - [0.73939, 0.56239, 0.20318], - [0.74685, 0.56373, 0.20737], - [0.75427, 0.56503, 0.21176], - [0.76163, 0.56634, 0.21632], - [0.76894, 0.56763, 0.22105], - [0.77621, 0.5689, 0.22593], - [0.78342, 0.57016, 0.23096], - [0.79057, 0.57142, 0.23616], - [0.79767, 0.57268, 0.24149], - [0.80471, 0.57393, 0.24696], - [0.81169, 0.57519, 0.25257], - [0.81861, 0.57646, 0.2583], - [0.82547, 0.57773, 0.2642], - [0.83227, 0.57903, 0.27021], - [0.839, 0.58034, 0.27635], - [0.84566, 0.58167, 0.28263], - [0.85225, 0.58304, 0.28904], - [0.85875, 0.58444, 0.29557], - [0.86517, 0.58588, 0.30225], - [0.87151, 0.58735, 0.30911], - [0.87774, 0.58887, 0.31608], - [0.88388, 0.59045, 0.32319], - [0.8899, 0.59209, 0.33045], - [0.89581, 0.59377, 0.33787], - [0.90159, 0.59551, 0.34543], - [0.90724, 0.59732, 0.35314], - [0.91275, 0.59919, 0.36099], - [0.9181, 0.60113, 0.369], - [0.9233, 0.60314, 0.37714], - [0.92832, 0.60521, 0.3854], - [0.93318, 0.60737, 0.39382], - [0.93785, 0.60958, 0.40235], - [0.94233, 0.61187, 0.41101], - [0.94661, 0.61422, 0.41977], - [0.9507, 0.61665, 0.42862], - [0.95457, 0.61914, 0.43758], - [0.95824, 0.62167, 0.4466], - [0.9617, 0.62428, 0.4557], - [0.96494, 0.62693, 0.46486], - [0.96798, 0.62964, 0.47406], - [0.9708, 0.63239, 0.48329], - [0.97342, 0.63518, 0.49255], - [0.97584, 0.63801, 0.50183], - [0.97805, 0.64087, 0.51109], - [0.98008, 0.64375, 0.52035], - [0.98192, 0.64666, 0.5296], - [0.98357, 0.64959, 0.53882], - [0.98507, 0.65252, 0.548], - [0.98639, 0.65547, 0.55714], - [0.98757, 0.65842, 0.56623], - [0.9886, 0.66138, 0.57526], - [0.9895, 0.66433, 0.58425], - [0.99027, 0.66728, 0.59317], - [0.99093, 0.67023, 0.60203], - [0.99148, 0.67316, 0.61084], - [0.99194, 0.67609, 0.61958], - [0.9923, 0.67901, 0.62825], - [0.99259, 0.68191, 0.63687], - [0.99281, 0.68482, 0.64542], - [0.99297, 0.68771, 0.65393], - [0.99306, 0.69058, 0.6624], - [0.99311, 0.69345, 0.67081], - [0.99311, 0.69631, 0.67918], - [0.99307, 0.69916, 0.68752], - [0.993, 0.70201, 0.69583], - [0.9929, 0.70485, 0.70411], - [0.99277, 0.70769, 0.71238], - [0.99262, 0.71053, 0.72064], - [0.99245, 0.71337, 0.72889], - [0.99226, 0.71621, 0.73715], - [0.99205, 0.71905, 0.7454], - [0.99184, 0.72189, 0.75367], - [0.99161, 0.72475, 0.76196], - [0.99137, 0.72761, 0.77027], - [0.99112, 0.73049, 0.77861], - [0.99086, 0.73337, 0.78698], - [0.99059, 0.73626, 0.79537], - [0.99031, 0.73918, 0.80381], - [0.99002, 0.7421, 0.81229], - [0.98972, 0.74504, 0.8208], - [0.98941, 0.748, 0.82937], - [0.98909, 0.75097, 0.83798], - [0.98875, 0.75395, 0.84663], - [0.98841, 0.75695, 0.85533], - [0.98805, 0.75996, 0.86408], - [0.98767, 0.763, 0.87286], - [0.98728, 0.76605, 0.8817], - [0.98687, 0.7691, 0.89057], - [0.98643, 0.77218, 0.89949], - [0.98598, 0.77527, 0.90845], - [0.9855, 0.77838, 0.91744], - [0.985, 0.7815, 0.92647], - [0.98447, 0.78462, 0.93553], - [0.98391, 0.78776, 0.94463], - [0.98332, 0.79091, 0.95375], - [0.9827, 0.79407, 0.9629], - [0.98205, 0.79723, 0.97207], - [0.98135, 0.80041, 0.98127], -]; - -export const colormap_arcon_data: Array<[number, number, number]> = [ - [0.18063, 0.12992, 0.30024], - [0.18461, 0.13336, 0.30378], - [0.18859, 0.13683, 0.30733], - [0.19255, 0.14032, 0.3109], - [0.19655, 0.14383, 0.31444], - [0.20049, 0.14734, 0.31801], - [0.20451, 0.15085, 0.32158], - [0.20849, 0.15437, 0.32515], - [0.2125, 0.15792, 0.32875], - [0.21652, 0.16149, 0.33235], - [0.22054, 0.165, 0.33593], - [0.22453, 0.16858, 0.33954], - [0.2286, 0.17214, 0.34314], - [0.23263, 0.17571, 0.34675], - [0.2367, 0.17931, 0.35037], - [0.24074, 0.18289, 0.35398], - [0.24481, 0.1865, 0.35762], - [0.24893, 0.1901, 0.36124], - [0.25303, 0.19373, 0.36487], - [0.25715, 0.19734, 0.36852], - [0.26128, 0.20094, 0.37216], - [0.26543, 0.20461, 0.37581], - [0.2696, 0.20823, 0.37946], - [0.27378, 0.21188, 0.38312], - [0.27798, 0.2155, 0.38677], - [0.2822, 0.21915, 0.39043], - [0.28642, 0.22281, 0.3941], - [0.29069, 0.22646, 0.39777], - [0.29496, 0.23008, 0.40143], - [0.29928, 0.23373, 0.40509], - [0.30359, 0.23742, 0.40876], - [0.30794, 0.24104, 0.41244], - [0.31231, 0.24467, 0.41609], - [0.31673, 0.24835, 0.41976], - [0.32115, 0.25198, 0.4234], - [0.3256, 0.25561, 0.42707], - [0.3301, 0.25925, 0.43071], - [0.33462, 0.26286, 0.43435], - [0.33916, 0.26647, 0.43799], - [0.34371, 0.27008, 0.44162], - [0.34832, 0.27367, 0.44523], - [0.35296, 0.27725, 0.44884], - [0.35764, 0.28079, 0.45243], - [0.36233, 0.28434, 0.45599], - [0.36706, 0.28787, 0.45956], - [0.37182, 0.29139, 0.46309], - [0.37663, 0.29486, 0.46662], - [0.38146, 0.29832, 0.47012], - [0.38631, 0.30175, 0.47358], - [0.39123, 0.30517, 0.47703], - [0.39615, 0.30855, 0.48045], - [0.40112, 0.31187, 0.48384], - [0.40611, 0.31519, 0.4872], - [0.41112, 0.31845, 0.49052], - [0.41617, 0.32167, 0.4938], - [0.42124, 0.32485, 0.49704], - [0.42634, 0.32799, 0.50023], - [0.43147, 0.33107, 0.50338], - [0.43661, 0.33412, 0.50649], - [0.44178, 0.3371, 0.50955], - [0.44695, 0.34002, 0.51254], - [0.45215, 0.34289, 0.51548], - [0.45735, 0.34567, 0.51838], - [0.46256, 0.34842, 0.5212], - [0.46779, 0.35109, 0.52396], - [0.47301, 0.35368, 0.52667], - [0.47824, 0.35622, 0.5293], - [0.48346, 0.35866, 0.53186], - [0.48868, 0.36105, 0.53435], - [0.49389, 0.36336, 0.53678], - [0.49909, 0.36559, 0.53912], - [0.50428, 0.36773, 0.54138], - [0.50944, 0.36981, 0.54359], - [0.5146, 0.37179, 0.54572], - [0.51971, 0.37371, 0.54776], - [0.52482, 0.37553, 0.54973], - [0.52989, 0.37729, 0.55162], - [0.53494, 0.37895, 0.55343], - [0.53995, 0.38054, 0.55517], - [0.54493, 0.38204, 0.55684], - [0.54988, 0.38348, 0.55842], - [0.55479, 0.38482, 0.55995], - [0.55967, 0.38609, 0.56139], - [0.5645, 0.38729, 0.56277], - [0.56929, 0.38842, 0.56407], - [0.57405, 0.38948, 0.56529], - [0.57878, 0.39046, 0.56647], - [0.58346, 0.39139, 0.56758], - [0.5881, 0.39224, 0.56862], - [0.59272, 0.39303, 0.56961], - [0.59728, 0.39377, 0.57054], - [0.60181, 0.39446, 0.57142], - [0.60631, 0.39509, 0.57225], - [0.61079, 0.39568, 0.57304], - [0.61522, 0.39621, 0.57377], - [0.61963, 0.3967, 0.57446], - [0.62402, 0.39717, 0.57513], - [0.62837, 0.39761, 0.57577], - [0.63271, 0.39801, 0.57637], - [0.63703, 0.39839, 0.57694], - [0.64132, 0.39875, 0.57749], - [0.64562, 0.39909, 0.57803], - [0.64991, 0.39943, 0.57856], - [0.65419, 0.39978, 0.57909], - [0.65846, 0.40013, 0.57961], - [0.66275, 0.4005, 0.58013], - [0.66704, 0.40088, 0.58066], - [0.67134, 0.40128, 0.58121], - [0.67566, 0.40171, 0.58178], - [0.67999, 0.40218, 0.58238], - [0.68435, 0.40272, 0.58301], - [0.68875, 0.40332, 0.58369], - [0.69317, 0.40397, 0.58441], - [0.69762, 0.4047, 0.58519], - [0.70211, 0.40553, 0.58603], - [0.70665, 0.40645, 0.58693], - [0.71122, 0.40747, 0.58792], - [0.71583, 0.40861, 0.58898], - [0.72047, 0.40989, 0.59014], - [0.72516, 0.41129, 0.59141], - [0.72988, 0.41285, 0.59277], - [0.73462, 0.41455, 0.59423], - [0.73939, 0.41642, 0.59581], - [0.74417, 0.41844, 0.59751], - [0.74895, 0.42065, 0.59933], - [0.75373, 0.42302, 0.60126], - [0.75848, 0.42558, 0.60332], - [0.7632, 0.4283, 0.60549], - [0.76786, 0.4312, 0.60779], - [0.77246, 0.43425, 0.61018], - [0.77698, 0.43747, 0.61269], - [0.78138, 0.44082, 0.6153], - [0.78567, 0.44434, 0.61799], - [0.78982, 0.44795, 0.62078], - [0.79382, 0.4517, 0.62362], - [0.79765, 0.45553, 0.62652], - [0.8013, 0.45945, 0.62948], - [0.80476, 0.46342, 0.63248], - [0.80802, 0.46745, 0.6355], - [0.81107, 0.47152, 0.63854], - [0.81391, 0.47561, 0.64158], - [0.81654, 0.4797, 0.64462], - [0.81895, 0.48377, 0.64766], - [0.82115, 0.48786, 0.65067], - [0.82315, 0.4919, 0.65366], - [0.82494, 0.4959, 0.65662], - [0.82655, 0.49987, 0.65954], - [0.82796, 0.5038, 0.66243], - [0.8292, 0.50768, 0.66527], - [0.83027, 0.5115, 0.66808], - [0.83119, 0.51528, 0.67085], - [0.83196, 0.51901, 0.67357], - [0.8326, 0.52267, 0.67625], - [0.83311, 0.5263, 0.67889], - [0.83351, 0.52987, 0.68149], - [0.83381, 0.53339, 0.68406], - [0.83402, 0.53689, 0.6866], - [0.83415, 0.54032, 0.68911], - [0.8342, 0.54373, 0.69158], - [0.83418, 0.54711, 0.69403], - [0.83411, 0.55045, 0.69646], - [0.83399, 0.55377, 0.69886], - [0.83382, 0.55707, 0.70125], - [0.83362, 0.56035, 0.70362], - [0.83339, 0.56361, 0.70598], - [0.83314, 0.56685, 0.70832], - [0.83287, 0.57008, 0.71065], - [0.83258, 0.57331, 0.71297], - [0.83229, 0.57653, 0.7153], - [0.83199, 0.57975, 0.71761], - [0.83169, 0.58295, 0.71992], - [0.83139, 0.58617, 0.72222], - [0.83109, 0.58938, 0.72453], - [0.83081, 0.59261, 0.72684], - [0.83053, 0.59583, 0.72915], - [0.83027, 0.59907, 0.73146], - [0.83003, 0.6023, 0.73378], - [0.82981, 0.60555, 0.7361], - [0.8296, 0.60882, 0.73843], - [0.82942, 0.61209, 0.74076], - [0.82927, 0.61537, 0.74311], - [0.82914, 0.61868, 0.74545], - [0.82904, 0.62198, 0.74781], - [0.82896, 0.62531, 0.75017], - [0.82892, 0.62865, 0.75254], - [0.82891, 0.63201, 0.75493], - [0.82893, 0.63538, 0.75732], - [0.82898, 0.63877, 0.75971], - [0.82907, 0.64218, 0.76212], - [0.82919, 0.6456, 0.76455], - [0.82935, 0.64904, 0.76697], - [0.82954, 0.6525, 0.76941], - [0.82977, 0.65598, 0.77186], - [0.83003, 0.65947, 0.77432], - [0.83034, 0.66298, 0.77679], - [0.83068, 0.6665, 0.77927], - [0.83106, 0.67005, 0.78176], - [0.83147, 0.67361, 0.78426], - [0.83193, 0.6772, 0.78677], - [0.83241, 0.68078, 0.78929], - [0.83294, 0.6844, 0.79181], - [0.83351, 0.68803, 0.79435], - [0.83411, 0.69168, 0.79689], - [0.83474, 0.69534, 0.79945], - [0.83542, 0.69901, 0.80201], - [0.83613, 0.70271, 0.80459], - [0.83687, 0.70642, 0.80717], - [0.83765, 0.71014, 0.80975], - [0.83846, 0.71388, 0.81235], - [0.83931, 0.71764, 0.81495], - [0.84019, 0.7214, 0.81757], - [0.8411, 0.72519, 0.82018], - [0.84205, 0.72897, 0.82282], - [0.84302, 0.73278, 0.82545], - [0.84402, 0.7366, 0.82809], - [0.84505, 0.74043, 0.83074], - [0.84611, 0.74427, 0.83339], - [0.8472, 0.74813, 0.83605], - [0.84831, 0.75199, 0.83871], - [0.84946, 0.75587, 0.84139], - [0.85062, 0.75975, 0.84406], - [0.85181, 0.76365, 0.84674], - [0.85302, 0.76755, 0.84943], - [0.85425, 0.77147, 0.85212], - [0.85551, 0.77539, 0.85482], - [0.85678, 0.77932, 0.85752], - [0.85807, 0.78327, 0.86023], - [0.85939, 0.78722, 0.86294], - [0.86072, 0.79117, 0.86565], - [0.86207, 0.79514, 0.86837], - [0.86343, 0.79911, 0.87109], - [0.8648, 0.80309, 0.87381], - [0.8662, 0.80708, 0.87654], - [0.8676, 0.81107, 0.87927], - [0.86903, 0.81506, 0.88201], - [0.87045, 0.81906, 0.88475], - [0.8719, 0.82308, 0.88749], - [0.87334, 0.8271, 0.89023], - [0.87481, 0.83112, 0.89298], - [0.87628, 0.83514, 0.89573], - [0.87776, 0.83917, 0.89848], - [0.87924, 0.84321, 0.90124], - [0.88073, 0.84725, 0.904], - [0.88223, 0.85129, 0.90676], - [0.88374, 0.85535, 0.90952], - [0.88524, 0.8594, 0.91229], - [0.88676, 0.86346, 0.91505], - [0.88827, 0.86752, 0.91783], - [0.88979, 0.87158, 0.92059], - [0.89132, 0.87565, 0.92337], - [0.89284, 0.87972, 0.92614], - [0.89437, 0.8838, 0.92892], - [0.89589, 0.88787, 0.9317], - [0.89742, 0.89195, 0.93448], - [0.89895, 0.89604, 0.93727], - [0.90047, 0.90012, 0.94005], -]; - -export const colormap_bamako_data: Array<[number, number, number]> = [ - [0.0011753, 0.25004, 0.3], - [0.0039003, 0.25157, 0.29861], - [0.006602, 0.25305, 0.29722], - [0.0092914, 0.25456, 0.29581], - [0.012175, 0.25604, 0.2944], - [0.014801, 0.25755, 0.293], - [0.01745, 0.25907, 0.29161], - [0.020096, 0.26057, 0.29018], - [0.022743, 0.26208, 0.28878], - [0.025398, 0.26361, 0.28735], - [0.028064, 0.26511, 0.28592], - [0.030746, 0.26664, 0.2845], - [0.033437, 0.26816, 0.28309], - [0.036369, 0.26971, 0.28165], - [0.039136, 0.27124, 0.28021], - [0.041941, 0.27278, 0.27878], - [0.044597, 0.27432, 0.27734], - [0.047216, 0.27589, 0.27591], - [0.049816, 0.27743, 0.27443], - [0.052305, 0.279, 0.27298], - [0.054846, 0.28053, 0.27151], - [0.057331, 0.28213, 0.27007], - [0.059903, 0.28369, 0.2686], - [0.062324, 0.28526, 0.2671], - [0.064737, 0.28684, 0.26564], - [0.067177, 0.28844, 0.26416], - [0.069647, 0.29003, 0.26267], - [0.072007, 0.29165, 0.26118], - [0.074435, 0.29324, 0.25969], - [0.076803, 0.29484, 0.25817], - [0.079232, 0.29647, 0.25667], - [0.081738, 0.29808, 0.25518], - [0.084163, 0.29972, 0.25365], - [0.086556, 0.30134, 0.25213], - [0.089008, 0.30298, 0.25059], - [0.091487, 0.30463, 0.24907], - [0.093906, 0.3063, 0.24754], - [0.096327, 0.30793, 0.24598], - [0.098845, 0.30961, 0.24443], - [0.10132, 0.31127, 0.24288], - [0.10384, 0.31294, 0.24134], - [0.10637, 0.31461, 0.23978], - [0.10884, 0.31632, 0.23821], - [0.1114, 0.318, 0.23666], - [0.11391, 0.3197, 0.23509], - [0.11648, 0.32139, 0.23347], - [0.11904, 0.32311, 0.23191], - [0.12156, 0.32481, 0.2303], - [0.12416, 0.32653, 0.22873], - [0.12676, 0.32826, 0.22712], - [0.12938, 0.33, 0.22551], - [0.132, 0.33173, 0.22389], - [0.13465, 0.33348, 0.22228], - [0.13728, 0.33524, 0.22068], - [0.13988, 0.33699, 0.21904], - [0.14258, 0.33874, 0.21741], - [0.14528, 0.34051, 0.21578], - [0.14793, 0.34229, 0.21413], - [0.15062, 0.34406, 0.21248], - [0.15331, 0.34584, 0.21083], - [0.15607, 0.34765, 0.20917], - [0.15879, 0.34944, 0.20751], - [0.16154, 0.35125, 0.20585], - [0.16429, 0.35306, 0.20419], - [0.16705, 0.35489, 0.20248], - [0.16983, 0.35671, 0.20078], - [0.17259, 0.35853, 0.1991], - [0.1754, 0.36036, 0.19742], - [0.17824, 0.36222, 0.19572], - [0.18102, 0.36406, 0.19403], - [0.18387, 0.36593, 0.1923], - [0.18672, 0.36779, 0.19058], - [0.18959, 0.36966, 0.18887], - [0.19246, 0.37154, 0.18714], - [0.19535, 0.37344, 0.18542], - [0.19825, 0.37533, 0.18364], - [0.20116, 0.37724, 0.18189], - [0.20413, 0.37915, 0.18014], - [0.20706, 0.38108, 0.17841], - [0.21001, 0.383, 0.1766], - [0.21297, 0.38493, 0.17486], - [0.21599, 0.38688, 0.17306], - [0.21898, 0.38884, 0.17127], - [0.22199, 0.39081, 0.1695], - [0.22501, 0.39277, 0.16768], - [0.22809, 0.39476, 0.16585], - [0.23115, 0.39674, 0.16407], - [0.23423, 0.39875, 0.16224], - [0.23735, 0.40078, 0.16037], - [0.24043, 0.40279, 0.15857], - [0.24357, 0.40482, 0.15671], - [0.24673, 0.40687, 0.15484], - [0.24989, 0.40893, 0.15296], - [0.2531, 0.411, 0.15109], - [0.25629, 0.41308, 0.14922], - [0.25954, 0.41517, 0.14733], - [0.26278, 0.41728, 0.14546], - [0.26606, 0.41939, 0.14352], - [0.26935, 0.42151, 0.14161], - [0.27265, 0.42366, 0.13963], - [0.276, 0.42581, 0.13775], - [0.27935, 0.42799, 0.13575], - [0.28274, 0.43017, 0.13382], - [0.28611, 0.43238, 0.13185], - [0.28956, 0.43459, 0.12989], - [0.293, 0.43682, 0.12788], - [0.29648, 0.43906, 0.12588], - [0.29998, 0.44132, 0.12382], - [0.3035, 0.44361, 0.12179], - [0.30706, 0.44589, 0.11977], - [0.31066, 0.44821, 0.11773], - [0.31426, 0.45054, 0.11568], - [0.3179, 0.45289, 0.11362], - [0.32156, 0.45525, 0.11153], - [0.32526, 0.45763, 0.10944], - [0.32901, 0.46003, 0.10731], - [0.33277, 0.46245, 0.10513], - [0.33654, 0.4649, 0.10304], - [0.34037, 0.46736, 0.10085], - [0.34422, 0.46984, 0.098693], - [0.34812, 0.47233, 0.096453], - [0.35204, 0.47486, 0.094325], - [0.35601, 0.47738, 0.092102], - [0.36, 0.47994, 0.089849], - [0.36403, 0.48251, 0.087617], - [0.36811, 0.4851, 0.085276], - [0.37221, 0.48772, 0.082993], - [0.37638, 0.49034, 0.080686], - [0.38057, 0.49296, 0.078304], - [0.3848, 0.49562, 0.075955], - [0.38909, 0.49829, 0.073656], - [0.39341, 0.50095, 0.071224], - [0.39779, 0.50362, 0.068802], - [0.4022, 0.5063, 0.066264], - [0.40668, 0.50898, 0.063774], - [0.4112, 0.51164, 0.061172], - [0.41578, 0.51431, 0.058651], - [0.4204, 0.51695, 0.05607], - [0.42509, 0.51956, 0.053359], - [0.42981, 0.52214, 0.050712], - [0.4346, 0.5247, 0.047969], - [0.43943, 0.52722, 0.045272], - [0.44432, 0.52967, 0.042483], - [0.44924, 0.53207, 0.039697], - [0.45421, 0.5344, 0.036906], - [0.45922, 0.53666, 0.034001], - [0.46428, 0.53884, 0.031435], - [0.46935, 0.54092, 0.028957], - [0.47444, 0.54291, 0.026597], - [0.47956, 0.5448, 0.024363], - [0.48468, 0.54659, 0.022265], - [0.48982, 0.54827, 0.020312], - [0.49497, 0.54985, 0.018512], - [0.5001, 0.55132, 0.016876], - [0.50524, 0.55269, 0.015412], - [0.51038, 0.55397, 0.014132], - [0.5155, 0.55517, 0.013033], - [0.52063, 0.55628, 0.01218], - [0.52575, 0.55735, 0.011416], - [0.53088, 0.55835, 0.010839], - [0.53601, 0.55933, 0.010585], - [0.54115, 0.5603, 0.010612], - [0.54633, 0.56126, 0.010945], - [0.55153, 0.56225, 0.011649], - [0.55677, 0.56328, 0.012516], - [0.56207, 0.56438, 0.01365], - [0.56742, 0.56555, 0.015118], - [0.57285, 0.56684, 0.016927], - [0.57835, 0.56824, 0.019098], - [0.58394, 0.56978, 0.021653], - [0.58963, 0.57149, 0.024617], - [0.59541, 0.57336, 0.028014], - [0.60129, 0.5754, 0.03187], - [0.60728, 0.57763, 0.036408], - [0.61335, 0.58006, 0.041287], - [0.61954, 0.58268, 0.046299], - [0.62581, 0.58551, 0.051565], - [0.63218, 0.58853, 0.057023], - [0.63862, 0.59176, 0.062625], - [0.64514, 0.59517, 0.068288], - [0.65173, 0.59876, 0.074092], - [0.65837, 0.60254, 0.079969], - [0.66506, 0.60647, 0.085984], - [0.6718, 0.61057, 0.0922], - [0.67856, 0.6148, 0.098456], - [0.68534, 0.61918, 0.10476], - [0.69213, 0.62366, 0.11129], - [0.69891, 0.62825, 0.11783], - [0.70569, 0.63293, 0.12447], - [0.71245, 0.63769, 0.13125], - [0.71918, 0.64252, 0.1381], - [0.72588, 0.6474, 0.14503], - [0.73253, 0.65232, 0.15201], - [0.73912, 0.65728, 0.15912], - [0.74564, 0.66226, 0.16629], - [0.7521, 0.66724, 0.17352], - [0.75847, 0.67223, 0.18082], - [0.76475, 0.67721, 0.18823], - [0.77094, 0.68215, 0.19562], - [0.77702, 0.68709, 0.20308], - [0.78299, 0.69199, 0.21059], - [0.78886, 0.69684, 0.21813], - [0.79459, 0.70164, 0.2257], - [0.80021, 0.7064, 0.23325], - [0.8057, 0.7111, 0.24084], - [0.81106, 0.71574, 0.24845], - [0.81631, 0.72031, 0.25601], - [0.82142, 0.72482, 0.26361], - [0.8264, 0.72926, 0.27115], - [0.83127, 0.73364, 0.2787], - [0.83602, 0.73795, 0.28619], - [0.84066, 0.74221, 0.29369], - [0.84519, 0.74639, 0.30114], - [0.84961, 0.75052, 0.30859], - [0.85394, 0.75459, 0.31598], - [0.85818, 0.7586, 0.32333], - [0.86234, 0.76255, 0.33065], - [0.86641, 0.76646, 0.33794], - [0.87042, 0.77032, 0.3452], - [0.87436, 0.77414, 0.35241], - [0.87824, 0.77792, 0.3596], - [0.88207, 0.78167, 0.36676], - [0.88585, 0.78537, 0.37388], - [0.88958, 0.78905, 0.38098], - [0.89328, 0.7927, 0.38804], - [0.89694, 0.79632, 0.39508], - [0.90057, 0.79992, 0.40209], - [0.90417, 0.8035, 0.40909], - [0.90775, 0.80706, 0.41606], - [0.9113, 0.8106, 0.423], - [0.91484, 0.81412, 0.42995], - [0.91835, 0.81764, 0.43686], - [0.92186, 0.82114, 0.44376], - [0.92534, 0.82462, 0.45064], - [0.92882, 0.8281, 0.45751], - [0.93228, 0.83157, 0.46438], - [0.93573, 0.83502, 0.47121], - [0.93918, 0.83847, 0.47804], - [0.94261, 0.84192, 0.48486], - [0.94603, 0.84535, 0.49169], - [0.94945, 0.84878, 0.49849], - [0.95286, 0.85221, 0.50528], - [0.95627, 0.85563, 0.51207], - [0.95966, 0.85904, 0.51886], - [0.96305, 0.86246, 0.52563], - [0.96643, 0.86586, 0.53241], - [0.96981, 0.86927, 0.53917], - [0.97318, 0.87268, 0.54594], - [0.97654, 0.87608, 0.55269], - [0.9799, 0.87948, 0.55945], - [0.98325, 0.88288, 0.5662], - [0.98659, 0.88628, 0.57296], - [0.98993, 0.88968, 0.57971], - [0.99326, 0.89308, 0.58645], - [0.99658, 0.89648, 0.5932], - [0.9999, 0.89988, 0.59995], -]; - -export const colormap_berlin_data: Array<[number, number, number]> = [ - [0.62108, 0.69018, 0.99951], - [0.61216, 0.68923, 0.99537], - [0.6032, 0.68825, 0.99124], - [0.5942, 0.68726, 0.98709], - [0.58517, 0.68625, 0.98292], - [0.57609, 0.68522, 0.97873], - [0.56696, 0.68417, 0.97452], - [0.55779, 0.6831, 0.97029], - [0.54859, 0.68199, 0.96602], - [0.53933, 0.68086, 0.9617], - [0.53003, 0.67969, 0.95735], - [0.52069, 0.67848, 0.95294], - [0.51129, 0.67723, 0.94847], - [0.50186, 0.67591, 0.94392], - [0.49237, 0.67453, 0.9393], - [0.48283, 0.67308, 0.93457], - [0.47324, 0.67153, 0.92975], - [0.46361, 0.6699, 0.92481], - [0.45393, 0.66815, 0.91974], - [0.44421, 0.66628, 0.91452], - [0.43444, 0.66427, 0.90914], - [0.42465, 0.66212, 0.90359], - [0.41482, 0.65979, 0.89785], - [0.40498, 0.65729, 0.89191], - [0.39514, 0.65458, 0.88575], - [0.3853, 0.65167, 0.87937], - [0.37549, 0.64854, 0.87276], - [0.36574, 0.64516, 0.8659], - [0.35606, 0.64155, 0.8588], - [0.34645, 0.63769, 0.85145], - [0.33698, 0.63357, 0.84386], - [0.32764, 0.62919, 0.83602], - [0.31849, 0.62455, 0.82794], - [0.30954, 0.61966, 0.81963], - [0.30078, 0.6145, 0.81111], - [0.29231, 0.60911, 0.80238], - [0.2841, 0.60348, 0.79347], - [0.27621, 0.59763, 0.78439], - [0.26859, 0.59158, 0.77514], - [0.26131, 0.58534, 0.76578], - [0.25437, 0.57891, 0.7563], - [0.24775, 0.57233, 0.74672], - [0.24146, 0.5656, 0.73707], - [0.23552, 0.55875, 0.72735], - [0.22984, 0.5518, 0.7176], - [0.2245, 0.54475, 0.7078], - [0.21948, 0.53763, 0.698], - [0.21469, 0.53043, 0.68819], - [0.21017, 0.52319, 0.67838], - [0.20589, 0.5159, 0.66858], - [0.20177, 0.5086, 0.65879], - [0.19788, 0.50126, 0.64903], - [0.19417, 0.4939, 0.63929], - [0.19056, 0.48654, 0.62957], - [0.18711, 0.47918, 0.6199], - [0.18375, 0.47183, 0.61024], - [0.1805, 0.46447, 0.60062], - [0.17737, 0.45712, 0.59104], - [0.17426, 0.44979, 0.58148], - [0.17122, 0.44247, 0.57197], - [0.16824, 0.43517, 0.56249], - [0.16529, 0.42788, 0.55302], - [0.16244, 0.42061, 0.5436], - [0.15954, 0.41337, 0.53421], - [0.15674, 0.40615, 0.52486], - [0.15391, 0.39893, 0.51552], - [0.15112, 0.39176, 0.50623], - [0.14835, 0.38459, 0.49697], - [0.14564, 0.37746, 0.48775], - [0.14288, 0.37034, 0.47854], - [0.14014, 0.36326, 0.46939], - [0.13747, 0.3562, 0.46024], - [0.13478, 0.34916, 0.45115], - [0.13208, 0.34215, 0.44209], - [0.1294, 0.33517, 0.43304], - [0.12674, 0.3282, 0.42404], - [0.12409, 0.32126, 0.41507], - [0.12146, 0.31435, 0.40614], - [0.1189, 0.30746, 0.39723], - [0.11632, 0.30061, 0.38838], - [0.11373, 0.29378, 0.37955], - [0.11119, 0.28698, 0.37075], - [0.10861, 0.28022, 0.362], - [0.10616, 0.2735, 0.35328], - [0.10367, 0.26678, 0.34459], - [0.10118, 0.26011, 0.33595], - [0.098776, 0.25347, 0.32734], - [0.096347, 0.24685, 0.31878], - [0.094059, 0.24026, 0.31027], - [0.091788, 0.23373, 0.30176], - [0.089506, 0.22725, 0.29332], - [0.087341, 0.2208, 0.28491], - [0.085142, 0.21436, 0.27658], - [0.083069, 0.20798, 0.26825], - [0.081098, 0.20163, 0.25999], - [0.07913, 0.19536, 0.25178], - [0.077286, 0.18914, 0.24359], - [0.075571, 0.18294, 0.2355], - [0.073993, 0.17683, 0.22743], - [0.07241, 0.17079, 0.21943], - [0.071045, 0.1648, 0.2115], - [0.069767, 0.1589, 0.20363], - [0.068618, 0.15304, 0.19582], - [0.06756, 0.14732, 0.18812], - [0.066665, 0.14167, 0.18045], - [0.065923, 0.13608, 0.17292], - [0.065339, 0.1307, 0.16546], - [0.064911, 0.12535, 0.15817], - [0.064636, 0.12013, 0.15095], - [0.064517, 0.11507, 0.14389], - [0.064554, 0.11022, 0.13696], - [0.064749, 0.10543, 0.13023], - [0.0651, 0.10085, 0.12357], - [0.065383, 0.096469, 0.11717], - [0.065574, 0.092338, 0.11101], - [0.065892, 0.088201, 0.10498], - [0.066388, 0.084134, 0.099288], - [0.067108, 0.080051, 0.093829], - [0.068193, 0.076099, 0.08847], - [0.06972, 0.072283, 0.083025], - [0.071639, 0.068654, 0.077544], - [0.073978, 0.065058, 0.07211], - [0.076596, 0.061657, 0.066651], - [0.079637, 0.05855, 0.061133], - [0.082963, 0.055666, 0.055745], - [0.086537, 0.052997, 0.050336], - [0.090315, 0.050699, 0.04504], - [0.09426, 0.048753, 0.039773], - [0.098319, 0.047041, 0.034683], - [0.10246, 0.045624, 0.030074], - [0.10673, 0.044705, 0.026012], - [0.11099, 0.043972, 0.022379], - [0.11524, 0.043596, 0.01915], - [0.11955, 0.043567, 0.016299], - [0.12381, 0.043861, 0.013797], - [0.1281, 0.044459, 0.011588], - [0.13232, 0.045229, 0.0095315], - [0.13645, 0.046164, 0.0078947], - [0.14063, 0.047374, 0.006502], - [0.14488, 0.048634, 0.0053266], - [0.14923, 0.049836, 0.0043455], - [0.15369, 0.050997, 0.0035374], - [0.15831, 0.05213, 0.0028824], - [0.16301, 0.053218, 0.0023628], - [0.16781, 0.05424, 0.0019629], - [0.17274, 0.055172, 0.001669], - [0.1778, 0.056018, 0.0014692], - [0.18286, 0.05682, 0.0013401], - [0.18806, 0.057574, 0.0012617], - [0.19323, 0.058514, 0.0012261], - [0.19846, 0.05955, 0.0012271], - [0.20378, 0.060501, 0.0012601], - [0.20909, 0.061486, 0.0013221], - [0.21447, 0.06271, 0.0014116], - [0.2199, 0.063823, 0.0015287], - [0.22535, 0.065027, 0.0016748], - [0.23086, 0.066297, 0.0018529], - [0.23642, 0.067645, 0.0020675], - [0.24202, 0.069092, 0.0023247], - [0.24768, 0.070458, 0.0026319], - [0.25339, 0.071986, 0.0029984], - [0.25918, 0.07364, 0.003435], - [0.265, 0.075237, 0.0039545], - [0.27093, 0.076965, 0.004571], - [0.27693, 0.078822, 0.0053006], - [0.28302, 0.080819, 0.0061608], - [0.2892, 0.082879, 0.0071713], - [0.29547, 0.085075, 0.0083494], - [0.30186, 0.08746, 0.0097258], - [0.30839, 0.089912, 0.011455], - [0.31502, 0.09253, 0.013324], - [0.32181, 0.095392, 0.015413], - [0.32874, 0.098396, 0.01778], - [0.3358, 0.10158, 0.020449], - [0.34304, 0.10498, 0.02344], - [0.35041, 0.10864, 0.026771], - [0.35795, 0.11256, 0.030456], - [0.36563, 0.11666, 0.034571], - [0.37347, 0.12097, 0.039115], - [0.38146, 0.12561, 0.043693], - [0.38958, 0.13046, 0.048471], - [0.39785, 0.13547, 0.053136], - [0.40622, 0.1408, 0.057848], - [0.41469, 0.14627, 0.062715], - [0.42323, 0.15198, 0.067685], - [0.43184, 0.15791, 0.073044], - [0.44044, 0.16403, 0.07862], - [0.44909, 0.17027, 0.084644], - [0.4577, 0.17667, 0.090869], - [0.46631, 0.18321, 0.097335], - [0.4749, 0.18989, 0.10406], - [0.48342, 0.19668, 0.11104], - [0.49191, 0.20352, 0.11819], - [0.50032, 0.21043, 0.1255], - [0.50869, 0.21742, 0.13298], - [0.51698, 0.22443, 0.14062], - [0.5252, 0.23154, 0.14835], - [0.53335, 0.23862, 0.15626], - [0.54144, 0.24575, 0.16423], - [0.54948, 0.25292, 0.17226], - [0.55746, 0.26009, 0.1804], - [0.56538, 0.26726, 0.18864], - [0.57327, 0.27446, 0.19692], - [0.58111, 0.28167, 0.20524], - [0.58892, 0.28889, 0.21362], - [0.59672, 0.29611, 0.22205], - [0.60448, 0.30335, 0.23053], - [0.61223, 0.31062, 0.23905], - [0.61998, 0.31787, 0.24762], - [0.62771, 0.32513, 0.25619], - [0.63544, 0.33244, 0.26481], - [0.64317, 0.33975, 0.27349], - [0.65092, 0.34706, 0.28218], - [0.65866, 0.3544, 0.29089], - [0.66642, 0.36175, 0.29964], - [0.67419, 0.36912, 0.30842], - [0.68198, 0.37652, 0.31722], - [0.68978, 0.38392, 0.32604], - [0.6976, 0.39135, 0.33493], - [0.70543, 0.39879, 0.3438], - [0.71329, 0.40627, 0.35272], - [0.72116, 0.41376, 0.36166], - [0.72905, 0.42126, 0.37062], - [0.73697, 0.4288, 0.37962], - [0.7449, 0.43635, 0.38864], - [0.75285, 0.44392, 0.39768], - [0.76083, 0.45151, 0.40675], - [0.76882, 0.45912, 0.41584], - [0.77684, 0.46676, 0.42496], - [0.78488, 0.47441, 0.43409], - [0.79293, 0.48208, 0.44327], - [0.80101, 0.48976, 0.45246], - [0.80911, 0.49749, 0.46167], - [0.81722, 0.50521, 0.47091], - [0.82536, 0.51296, 0.48017], - [0.83352, 0.52073, 0.48945], - [0.84169, 0.52853, 0.49876], - [0.84988, 0.53634, 0.5081], - [0.85809, 0.54416, 0.51745], - [0.86632, 0.55201, 0.52683], - [0.87457, 0.55988, 0.53622], - [0.88283, 0.56776, 0.54564], - [0.89111, 0.57567, 0.55508], - [0.89941, 0.58358, 0.56455], - [0.90772, 0.59153, 0.57404], - [0.91603, 0.59949, 0.58355], - [0.92437, 0.60747, 0.59309], - [0.93271, 0.61546, 0.60265], - [0.94108, 0.62348, 0.61223], - [0.94945, 0.63151, 0.62183], - [0.95783, 0.63956, 0.63147], - [0.96622, 0.64763, 0.64111], - [0.97462, 0.65572, 0.65079], - [0.98303, 0.66382, 0.66049], - [0.99145, 0.67194, 0.67022], - [0.99987, 0.68007, 0.67995], -]; - -export const colormap_bilbao_data: Array<[number, number, number]> = [ - [1, 1, 0.99991], - [0.99488, 0.99486, 0.99473], - [0.98976, 0.98973, 0.98957], - [0.98465, 0.9846, 0.98439], - [0.97954, 0.97948, 0.97922], - [0.97444, 0.97436, 0.97404], - [0.96934, 0.96925, 0.96886], - [0.96426, 0.96414, 0.96368], - [0.95919, 0.95905, 0.95849], - [0.95413, 0.95395, 0.95329], - [0.94907, 0.94887, 0.94808], - [0.94404, 0.94379, 0.94287], - [0.93901, 0.93872, 0.93764], - [0.93399, 0.93366, 0.93239], - [0.929, 0.92861, 0.92713], - [0.92403, 0.92357, 0.92186], - [0.91907, 0.91854, 0.91656], - [0.91414, 0.91353, 0.91124], - [0.90923, 0.90853, 0.9059], - [0.90435, 0.90354, 0.90053], - [0.8995, 0.89857, 0.89514], - [0.89469, 0.89362, 0.88971], - [0.8899, 0.8887, 0.88426], - [0.88516, 0.88381, 0.87878], - [0.88046, 0.87893, 0.87327], - [0.87582, 0.87409, 0.86773], - [0.87122, 0.86929, 0.86216], - [0.86668, 0.86453, 0.85655], - [0.86221, 0.8598, 0.85092], - [0.8578, 0.85513, 0.84526], - [0.85346, 0.8505, 0.83958], - [0.8492, 0.84592, 0.83387], - [0.84501, 0.84141, 0.82813], - [0.84091, 0.83696, 0.82239], - [0.8369, 0.83257, 0.81662], - [0.83298, 0.82826, 0.81084], - [0.82916, 0.82402, 0.80506], - [0.82543, 0.81985, 0.79928], - [0.82181, 0.81578, 0.79349], - [0.81829, 0.81178, 0.7877], - [0.81487, 0.80786, 0.78193], - [0.81157, 0.80403, 0.77616], - [0.80836, 0.80029, 0.77041], - [0.80526, 0.79664, 0.76468], - [0.80227, 0.79308, 0.75897], - [0.79938, 0.7896, 0.75329], - [0.79658, 0.78622, 0.74764], - [0.7939, 0.78291, 0.74201], - [0.7913, 0.77969, 0.73641], - [0.7888, 0.77656, 0.73085], - [0.78639, 0.77349, 0.72533], - [0.78406, 0.77051, 0.71983], - [0.78181, 0.76759, 0.71436], - [0.77963, 0.76475, 0.70894], - [0.77754, 0.76196, 0.70353], - [0.77549, 0.75924, 0.69816], - [0.77352, 0.75658, 0.69284], - [0.77161, 0.75396, 0.68752], - [0.76974, 0.7514, 0.68224], - [0.76792, 0.74887, 0.677], - [0.76616, 0.74638, 0.67176], - [0.76442, 0.74393, 0.66655], - [0.76272, 0.74151, 0.66137], - [0.76106, 0.73912, 0.6562], - [0.75942, 0.73674, 0.65105], - [0.75781, 0.73439, 0.6459], - [0.75622, 0.73205, 0.64078], - [0.75465, 0.72972, 0.63566], - [0.75309, 0.72739, 0.63056], - [0.75155, 0.72508, 0.62545], - [0.75001, 0.72275, 0.62036], - [0.74849, 0.72042, 0.61525], - [0.74696, 0.71808, 0.61016], - [0.74544, 0.71573, 0.60506], - [0.74393, 0.71336, 0.59996], - [0.74241, 0.71097, 0.59485], - [0.74088, 0.70854, 0.58974], - [0.73937, 0.70609, 0.58462], - [0.73783, 0.70359, 0.5795], - [0.73628, 0.70106, 0.57435], - [0.73474, 0.69848, 0.56921], - [0.73318, 0.69585, 0.56406], - [0.73161, 0.69316, 0.55889], - [0.73002, 0.69041, 0.55373], - [0.72842, 0.68759, 0.54857], - [0.72681, 0.68471, 0.54339], - [0.72519, 0.68175, 0.53823], - [0.72354, 0.67872, 0.53307], - [0.72189, 0.67561, 0.52792], - [0.72023, 0.67242, 0.5228], - [0.71855, 0.66915, 0.5177], - [0.71687, 0.6658, 0.51263], - [0.71517, 0.66238, 0.50762], - [0.71347, 0.65887, 0.50265], - [0.71176, 0.65529, 0.49776], - [0.71006, 0.65165, 0.49292], - [0.70836, 0.64793, 0.48819], - [0.70666, 0.64416, 0.48353], - [0.70497, 0.64035, 0.47899], - [0.7033, 0.63649, 0.47457], - [0.70163, 0.63258, 0.47026], - [0.69999, 0.62865, 0.46606], - [0.69837, 0.62469, 0.46202], - [0.69678, 0.62072, 0.45811], - [0.69521, 0.61674, 0.45435], - [0.69366, 0.61275, 0.45072], - [0.69216, 0.60879, 0.44723], - [0.69067, 0.60481, 0.44391], - [0.68923, 0.60086, 0.4407], - [0.68781, 0.59693, 0.43766], - [0.68642, 0.59303, 0.43474], - [0.68507, 0.58913, 0.43195], - [0.68375, 0.58529, 0.42927], - [0.68245, 0.58145, 0.42672], - [0.68119, 0.57766, 0.42428], - [0.67995, 0.57389, 0.42194], - [0.67875, 0.57015, 0.41971], - [0.67757, 0.56645, 0.41755], - [0.6764, 0.56277, 0.41547], - [0.67526, 0.5591, 0.41347], - [0.67413, 0.55547, 0.41153], - [0.67303, 0.55187, 0.40966], - [0.67194, 0.54828, 0.40784], - [0.67087, 0.54471, 0.40607], - [0.66981, 0.54115, 0.40433], - [0.66875, 0.53763, 0.40263], - [0.66771, 0.5341, 0.40098], - [0.66667, 0.5306, 0.39933], - [0.66565, 0.52711, 0.39773], - [0.66463, 0.52362, 0.39614], - [0.66363, 0.52013, 0.39457], - [0.66262, 0.51667, 0.39301], - [0.66162, 0.51321, 0.39148], - [0.66061, 0.50975, 0.38994], - [0.65962, 0.5063, 0.38843], - [0.65862, 0.50285, 0.38691], - [0.65764, 0.49941, 0.3854], - [0.65664, 0.49597, 0.38391], - [0.65565, 0.49253, 0.38241], - [0.65466, 0.48909, 0.38093], - [0.65368, 0.48566, 0.37943], - [0.65269, 0.48223, 0.37795], - [0.65171, 0.4788, 0.37647], - [0.65072, 0.47537, 0.37498], - [0.64973, 0.47194, 0.3735], - [0.64874, 0.4685, 0.37201], - [0.64775, 0.46507, 0.37052], - [0.64676, 0.46164, 0.36905], - [0.64577, 0.4582, 0.36755], - [0.64477, 0.45477, 0.36607], - [0.64377, 0.45132, 0.36457], - [0.64278, 0.44787, 0.36307], - [0.64177, 0.44444, 0.36158], - [0.64076, 0.44098, 0.36007], - [0.63975, 0.43754, 0.35856], - [0.63872, 0.43406, 0.35706], - [0.6377, 0.43061, 0.35554], - [0.63666, 0.42714, 0.35399], - [0.63561, 0.42365, 0.35245], - [0.63455, 0.42016, 0.35091], - [0.63348, 0.41667, 0.34933], - [0.63239, 0.41316, 0.34776], - [0.63128, 0.40964, 0.34615], - [0.63016, 0.40611, 0.34453], - [0.62901, 0.40254, 0.34291], - [0.62784, 0.39898, 0.34125], - [0.62664, 0.3954, 0.33957], - [0.62542, 0.3918, 0.33784], - [0.62416, 0.38817, 0.33609], - [0.62286, 0.38452, 0.33433], - [0.62152, 0.38085, 0.33251], - [0.62015, 0.37715, 0.33064], - [0.61872, 0.37341, 0.32874], - [0.61724, 0.36965, 0.32678], - [0.6157, 0.36586, 0.32478], - [0.6141, 0.36204, 0.32274], - [0.61245, 0.35818, 0.32062], - [0.61073, 0.35427, 0.31843], - [0.60893, 0.35035, 0.31619], - [0.60706, 0.34636, 0.31388], - [0.6051, 0.34235, 0.31148], - [0.60307, 0.33829, 0.30904], - [0.60095, 0.33421, 0.3065], - [0.59874, 0.33007, 0.30386], - [0.59644, 0.32588, 0.30116], - [0.59405, 0.32167, 0.29838], - [0.59156, 0.31742, 0.29552], - [0.58897, 0.31313, 0.29257], - [0.5863, 0.30882, 0.28955], - [0.58352, 0.30445, 0.28641], - [0.58065, 0.30006, 0.28323], - [0.57768, 0.29564, 0.27994], - [0.57462, 0.29121, 0.27658], - [0.57147, 0.28673, 0.27314], - [0.56822, 0.28227, 0.26963], - [0.56489, 0.27776, 0.26603], - [0.56148, 0.27324, 0.26236], - [0.55798, 0.26872, 0.25864], - [0.55441, 0.26418, 0.25486], - [0.55076, 0.25964, 0.251], - [0.54704, 0.2551, 0.24709], - [0.54326, 0.25053, 0.24312], - [0.53941, 0.24598, 0.23913], - [0.5355, 0.24146, 0.2351], - [0.53155, 0.23693, 0.231], - [0.52754, 0.23239, 0.22688], - [0.52349, 0.22787, 0.22273], - [0.5194, 0.22336, 0.21855], - [0.51526, 0.21885, 0.21434], - [0.51109, 0.21436, 0.2101], - [0.50688, 0.20987, 0.20587], - [0.50265, 0.2054, 0.20158], - [0.4984, 0.20092, 0.19733], - [0.49411, 0.19651, 0.19304], - [0.48979, 0.19205, 0.18876], - [0.48546, 0.18765, 0.18446], - [0.4811, 0.18319, 0.18015], - [0.47673, 0.1788, 0.17585], - [0.47234, 0.1744, 0.17157], - [0.46793, 0.17, 0.1673], - [0.4635, 0.16557, 0.16302], - [0.45906, 0.16122, 0.15875], - [0.4546, 0.15682, 0.15447], - [0.45012, 0.15241, 0.15024], - [0.44561, 0.14803, 0.14601], - [0.4411, 0.14364, 0.14178], - [0.43658, 0.13921, 0.1376], - [0.43203, 0.13486, 0.1334], - [0.42746, 0.13045, 0.12923], - [0.42286, 0.12601, 0.1251], - [0.41826, 0.12152, 0.12097], - [0.41364, 0.11708, 0.11692], - [0.409, 0.11265, 0.11291], - [0.40433, 0.1081, 0.10886], - [0.39965, 0.10363, 0.10484], - [0.39496, 0.099059, 0.10092], - [0.39024, 0.094525, 0.096994], - [0.3855, 0.089888, 0.093119], - [0.38077, 0.085202, 0.089344], - [0.376, 0.080518, 0.085505], - [0.3712, 0.075751, 0.081859], - [0.36642, 0.070994, 0.078058], - [0.36162, 0.066081, 0.074313], - [0.35684, 0.061064, 0.070322], - [0.35204, 0.056052, 0.066182], - [0.34729, 0.050813, 0.061797], - [0.34252, 0.045462, 0.057219], - [0.33776, 0.039997, 0.052327], - [0.33304, 0.034289, 0.047198], - [0.32831, 0.028994, 0.041679], - [0.3236, 0.023947, 0.03572], - [0.31891, 0.01913, 0.029528], - [0.31424, 0.014539, 0.023554], - [0.30961, 0.0099596, 0.017575], - [0.30498, 0.0058132, 0.011559], - [0.30038, 0.0018649, 0.005395], -]; - -export const colormap_broc_data: Array<[number, number, number]> = [ - [0.17081, 0.10027, 0.29985], - [0.17075, 0.10634, 0.30558], - [0.17061, 0.11229, 0.3113], - [0.1704, 0.11821, 0.31705], - [0.17013, 0.12404, 0.32282], - [0.16981, 0.12995, 0.3286], - [0.16943, 0.13572, 0.33441], - [0.169, 0.14158, 0.34021], - [0.1685, 0.14739, 0.34603], - [0.16797, 0.15317, 0.35187], - [0.16745, 0.159, 0.35775], - [0.16688, 0.1648, 0.36361], - [0.16626, 0.17063, 0.36951], - [0.16562, 0.17645, 0.37541], - [0.16499, 0.18231, 0.38135], - [0.16438, 0.18822, 0.38728], - [0.16373, 0.19411, 0.39324], - [0.16306, 0.19999, 0.39922], - [0.16241, 0.20596, 0.40522], - [0.16178, 0.21193, 0.41124], - [0.16114, 0.21792, 0.41729], - [0.1605, 0.22393, 0.42333], - [0.15991, 0.22999, 0.42941], - [0.1594, 0.23611, 0.43551], - [0.15895, 0.24223, 0.44162], - [0.15856, 0.24842, 0.44774], - [0.15825, 0.25463, 0.45388], - [0.15805, 0.26087, 0.46004], - [0.15799, 0.26715, 0.4662], - [0.1581, 0.27351, 0.47238], - [0.15841, 0.27989, 0.47855], - [0.15892, 0.28631, 0.48472], - [0.15966, 0.2928, 0.4909], - [0.16075, 0.29934, 0.49703], - [0.16216, 0.30592, 0.50316], - [0.16391, 0.31252, 0.50927], - [0.16599, 0.31919, 0.51534], - [0.16854, 0.32588, 0.52137], - [0.17149, 0.33265, 0.52735], - [0.1749, 0.33942, 0.53327], - [0.17874, 0.3462, 0.53913], - [0.183, 0.35303, 0.54493], - [0.18776, 0.35987, 0.55065], - [0.19288, 0.36673, 0.55629], - [0.19842, 0.37358, 0.56186], - [0.20439, 0.38045, 0.56734], - [0.21065, 0.3873, 0.57274], - [0.21727, 0.39416, 0.57805], - [0.22416, 0.40103, 0.5833], - [0.23136, 0.40786, 0.58847], - [0.23875, 0.4147, 0.59358], - [0.24637, 0.42151, 0.59862], - [0.25418, 0.42834, 0.60361], - [0.26213, 0.43515, 0.60855], - [0.27024, 0.44195, 0.61342], - [0.27844, 0.44874, 0.61828], - [0.28674, 0.45553, 0.6231], - [0.29515, 0.46231, 0.62789], - [0.30363, 0.4691, 0.63266], - [0.31216, 0.47588, 0.63742], - [0.32079, 0.48266, 0.64216], - [0.32944, 0.48945, 0.64689], - [0.33811, 0.49624, 0.65162], - [0.34685, 0.50304, 0.65634], - [0.35562, 0.50985, 0.66106], - [0.3644, 0.51666, 0.66578], - [0.37322, 0.52348, 0.67051], - [0.38206, 0.5303, 0.67522], - [0.39094, 0.53714, 0.67995], - [0.39982, 0.54397, 0.68468], - [0.40874, 0.55082, 0.68943], - [0.41768, 0.55768, 0.69416], - [0.42663, 0.56454, 0.69891], - [0.4356, 0.57141, 0.70367], - [0.44459, 0.57829, 0.70843], - [0.45359, 0.58519, 0.71319], - [0.46261, 0.59209, 0.71796], - [0.47166, 0.59899, 0.72273], - [0.4807, 0.6059, 0.72751], - [0.48977, 0.61282, 0.73231], - [0.49887, 0.61976, 0.7371], - [0.50797, 0.6267, 0.74189], - [0.51709, 0.63365, 0.7467], - [0.52622, 0.6406, 0.75151], - [0.53536, 0.64757, 0.75633], - [0.54452, 0.65454, 0.76115], - [0.55369, 0.66152, 0.76598], - [0.56289, 0.66851, 0.77081], - [0.57208, 0.67551, 0.77565], - [0.5813, 0.68251, 0.7805], - [0.59052, 0.68954, 0.78535], - [0.59977, 0.69656, 0.79021], - [0.60904, 0.70359, 0.79507], - [0.6183, 0.71063, 0.79995], - [0.62758, 0.71768, 0.80482], - [0.63689, 0.72474, 0.8097], - [0.64619, 0.73181, 0.81459], - [0.65552, 0.73889, 0.81948], - [0.66485, 0.74597, 0.82438], - [0.67421, 0.75305, 0.82929], - [0.68357, 0.76016, 0.8342], - [0.69295, 0.76727, 0.83911], - [0.70233, 0.77438, 0.84402], - [0.71174, 0.78151, 0.84894], - [0.72114, 0.78864, 0.85385], - [0.73057, 0.79577, 0.85877], - [0.74, 0.80291, 0.86368], - [0.74943, 0.81005, 0.86857], - [0.75888, 0.81719, 0.87343], - [0.76832, 0.82432, 0.87828], - [0.77776, 0.83145, 0.88308], - [0.7872, 0.83856, 0.88783], - [0.79662, 0.84564, 0.89251], - [0.80602, 0.8527, 0.8971], - [0.81538, 0.85971, 0.90156], - [0.82469, 0.86666, 0.90589], - [0.83394, 0.87352, 0.91001], - [0.84309, 0.88029, 0.91391], - [0.85212, 0.88692, 0.91752], - [0.86097, 0.89338, 0.92078], - [0.86962, 0.89963, 0.92365], - [0.87801, 0.90562, 0.92603], - [0.88606, 0.91129, 0.92785], - [0.8937, 0.91659, 0.92905], - [0.90086, 0.92145, 0.92956], - [0.90746, 0.92581, 0.92931], - [0.9134, 0.9296, 0.92825], - [0.91862, 0.93277, 0.92635], - [0.92307, 0.93528, 0.92359], - [0.92667, 0.9371, 0.91997], - [0.92943, 0.93822, 0.91554], - [0.93133, 0.93863, 0.91034], - [0.93239, 0.93838, 0.90443], - [0.93266, 0.93749, 0.8979], - [0.93219, 0.93601, 0.89081], - [0.93105, 0.93401, 0.88326], - [0.9293, 0.93154, 0.87532], - [0.92702, 0.92866, 0.86706], - [0.9243, 0.92545, 0.85854], - [0.92119, 0.92194, 0.84982], - [0.91776, 0.91818, 0.84094], - [0.91406, 0.91422, 0.83194], - [0.91015, 0.91011, 0.82285], - [0.90606, 0.90586, 0.81368], - [0.90184, 0.90151, 0.80447], - [0.89751, 0.89708, 0.79521], - [0.89309, 0.89259, 0.78594], - [0.88861, 0.88805, 0.77664], - [0.88407, 0.88347, 0.76733], - [0.87949, 0.87886, 0.75803], - [0.87489, 0.87423, 0.74871], - [0.87026, 0.86958, 0.7394], - [0.86561, 0.86491, 0.73009], - [0.86094, 0.86024, 0.72077], - [0.85625, 0.85553, 0.71146], - [0.85153, 0.8508, 0.70213], - [0.84679, 0.84606, 0.69282], - [0.84202, 0.84128, 0.68348], - [0.8372, 0.83645, 0.67414], - [0.83232, 0.83158, 0.66478], - [0.82739, 0.82665, 0.65542], - [0.82238, 0.82164, 0.64602], - [0.81728, 0.81655, 0.63661], - [0.81208, 0.81135, 0.62715], - [0.80676, 0.80603, 0.61766], - [0.80129, 0.80058, 0.60815], - [0.79568, 0.79499, 0.59859], - [0.7899, 0.78922, 0.589], - [0.78394, 0.78328, 0.5794], - [0.77778, 0.77715, 0.56976], - [0.77143, 0.77082, 0.56013], - [0.76486, 0.76428, 0.5505], - [0.75809, 0.75754, 0.54089], - [0.75112, 0.75061, 0.53133], - [0.74395, 0.74348, 0.52183], - [0.73661, 0.73616, 0.51242], - [0.72909, 0.72869, 0.50312], - [0.72143, 0.72106, 0.49397], - [0.71365, 0.71331, 0.48495], - [0.70576, 0.70546, 0.47611], - [0.69778, 0.69751, 0.46744], - [0.68975, 0.68951, 0.45895], - [0.68166, 0.68144, 0.45065], - [0.67355, 0.67336, 0.44254], - [0.66542, 0.66525, 0.4346], - [0.65729, 0.65714, 0.42684], - [0.64917, 0.64903, 0.41924], - [0.64105, 0.64093, 0.41179], - [0.63296, 0.63285, 0.40447], - [0.62488, 0.62478, 0.39727], - [0.61684, 0.61674, 0.39019], - [0.60881, 0.60873, 0.38321], - [0.6008, 0.60072, 0.3763], - [0.59283, 0.59275, 0.36945], - [0.58488, 0.5848, 0.36268], - [0.57695, 0.57687, 0.35596], - [0.56904, 0.56896, 0.34928], - [0.56116, 0.56108, 0.34265], - [0.55329, 0.55322, 0.33604], - [0.54546, 0.54538, 0.32949], - [0.53765, 0.53757, 0.32294], - [0.52985, 0.52977, 0.31642], - [0.52207, 0.52198, 0.30993], - [0.51433, 0.51424, 0.30344], - [0.50659, 0.5065, 0.29701], - [0.49888, 0.49879, 0.29056], - [0.4912, 0.49111, 0.28415], - [0.48352, 0.48342, 0.27777], - [0.47588, 0.47578, 0.27139], - [0.46825, 0.46814, 0.26503], - [0.46064, 0.46053, 0.2587], - [0.45307, 0.45296, 0.25239], - [0.4455, 0.44539, 0.24608], - [0.43798, 0.43786, 0.23981], - [0.43046, 0.43033, 0.23354], - [0.42296, 0.42283, 0.22732], - [0.4155, 0.41537, 0.22111], - [0.40805, 0.40792, 0.21489], - [0.40065, 0.4005, 0.20872], - [0.39323, 0.39309, 0.20257], - [0.38586, 0.38571, 0.19647], - [0.37851, 0.37836, 0.19034], - [0.37118, 0.37103, 0.18426], - [0.36389, 0.36373, 0.17824], - [0.35663, 0.35647, 0.17218], - [0.34937, 0.34922, 0.16619], - [0.34215, 0.342, 0.16021], - [0.33497, 0.33482, 0.1543], - [0.32778, 0.32764, 0.1484], - [0.32065, 0.32052, 0.14258], - [0.31352, 0.31341, 0.13676], - [0.30644, 0.30635, 0.13103], - [0.29937, 0.29931, 0.12531], - [0.29233, 0.2923, 0.11965], - [0.28532, 0.28532, 0.11406], - [0.27836, 0.27841, 0.10854], - [0.2714, 0.27151, 0.10314], - [0.26449, 0.26467, 0.097785], - [0.25761, 0.25787, 0.092474], - [0.25076, 0.25114, 0.087347], - [0.24394, 0.24442, 0.082262], - [0.2372, 0.2378, 0.077192], - [0.23042, 0.2312, 0.072349], - [0.22373, 0.22463, 0.067628], - [0.21709, 0.21818, 0.063025], - [0.21046, 0.21177, 0.058419], - [0.20394, 0.20539, 0.053781], - [0.19749, 0.19907, 0.048969], - [0.19115, 0.19284, 0.043546], - [0.18494, 0.18665, 0.037943], - [0.17882, 0.18051, 0.031907], - [0.1728, 0.17444, 0.026044], - [0.16695, 0.1684, 0.020145], - [0.16119, 0.16243, 0.014202], - [0.15554, 0.15649, 0.0080014], - [0.15005, 0.15056, 0.0019303], -]; - -export const colormap_broco_data: Array<[number, number, number]> = [ - [0.21429, 0.18467, 0.21821], - [0.21369, 0.18469, 0.22245], - [0.21315, 0.18487, 0.22685], - [0.21268, 0.18522, 0.23141], - [0.21227, 0.18574, 0.23612], - [0.21191, 0.1864, 0.24097], - [0.21159, 0.18728, 0.24599], - [0.21131, 0.18833, 0.2512], - [0.21109, 0.18953, 0.25653], - [0.21092, 0.19094, 0.26205], - [0.21081, 0.19255, 0.2677], - [0.21075, 0.19438, 0.27356], - [0.21074, 0.19638, 0.27955], - [0.21078, 0.19855, 0.28568], - [0.21088, 0.20094, 0.292], - [0.21104, 0.20358, 0.29845], - [0.21126, 0.20641, 0.30507], - [0.21155, 0.2094, 0.31181], - [0.2119, 0.21264, 0.31871], - [0.21232, 0.2161, 0.32573], - [0.21279, 0.21973, 0.33291], - [0.21336, 0.22357, 0.34018], - [0.21404, 0.22763, 0.34757], - [0.21477, 0.23189, 0.35506], - [0.21563, 0.23634, 0.36263], - [0.2166, 0.24096, 0.3703], - [0.21764, 0.24579, 0.37804], - [0.21882, 0.25081, 0.38584], - [0.22014, 0.25598, 0.3937], - [0.22156, 0.26135, 0.4016], - [0.22314, 0.26685, 0.40953], - [0.22483, 0.27251, 0.41748], - [0.22674, 0.27834, 0.42543], - [0.22878, 0.28428, 0.43337], - [0.23097, 0.29035, 0.44131], - [0.23333, 0.29656, 0.44923], - [0.23591, 0.30285, 0.45709], - [0.23863, 0.30929, 0.46493], - [0.24157, 0.31579, 0.4727], - [0.24466, 0.32237, 0.48043], - [0.248, 0.32904, 0.48809], - [0.2515, 0.33577, 0.49566], - [0.2552, 0.34257, 0.50316], - [0.25909, 0.34941, 0.51059], - [0.26316, 0.35631, 0.51793], - [0.26741, 0.36324, 0.52517], - [0.27187, 0.37021, 0.53232], - [0.27655, 0.37723, 0.53937], - [0.28136, 0.38425, 0.54634], - [0.28636, 0.3913, 0.5532], - [0.29157, 0.39836, 0.55997], - [0.29692, 0.40544, 0.56664], - [0.30241, 0.41252, 0.57321], - [0.30809, 0.41961, 0.5797], - [0.31393, 0.42669, 0.58608], - [0.3199, 0.43377, 0.59238], - [0.326, 0.44085, 0.59857], - [0.33227, 0.44793, 0.60469], - [0.33864, 0.45502, 0.61072], - [0.34514, 0.46207, 0.61667], - [0.35176, 0.46913, 0.62253], - [0.35849, 0.47617, 0.62832], - [0.36534, 0.4832, 0.63403], - [0.37228, 0.49022, 0.63967], - [0.37933, 0.49723, 0.64523], - [0.38646, 0.50423, 0.65073], - [0.3937, 0.5112, 0.65616], - [0.40102, 0.51817, 0.66152], - [0.4084, 0.52512, 0.66681], - [0.41586, 0.53206, 0.67206], - [0.42339, 0.53898, 0.67724], - [0.43101, 0.54589, 0.68235], - [0.43866, 0.55277, 0.68742], - [0.44639, 0.55965, 0.69243], - [0.45418, 0.56651, 0.69737], - [0.462, 0.57335, 0.70227], - [0.46989, 0.58017, 0.70711], - [0.47781, 0.58697, 0.71189], - [0.48577, 0.59376, 0.71662], - [0.49378, 0.60052, 0.72128], - [0.50183, 0.60728, 0.72589], - [0.50989, 0.61399, 0.73044], - [0.518, 0.6207, 0.73493], - [0.52612, 0.62737, 0.73936], - [0.53426, 0.63403, 0.74372], - [0.54243, 0.64065, 0.74801], - [0.5506, 0.64725, 0.75222], - [0.55878, 0.65382, 0.75637], - [0.56698, 0.66035, 0.76043], - [0.57517, 0.66685, 0.76441], - [0.58335, 0.67331, 0.76829], - [0.59154, 0.67972, 0.77209], - [0.59971, 0.6861, 0.77579], - [0.60786, 0.69243, 0.77938], - [0.61598, 0.6987, 0.78285], - [0.62408, 0.70491, 0.78621], - [0.63214, 0.71107, 0.78944], - [0.64016, 0.71716, 0.79253], - [0.64812, 0.72317, 0.79548], - [0.65605, 0.72911, 0.79828], - [0.66389, 0.73497, 0.80092], - [0.67166, 0.74072, 0.80338], - [0.67935, 0.74639, 0.80566], - [0.68695, 0.75195, 0.80776], - [0.69444, 0.75739, 0.80965], - [0.70182, 0.76271, 0.81133], - [0.70908, 0.7679, 0.81279], - [0.7162, 0.77295, 0.81401], - [0.72317, 0.77786, 0.81499], - [0.72999, 0.7826, 0.81572], - [0.73662, 0.78717, 0.81619], - [0.74307, 0.79156, 0.81637], - [0.74931, 0.79576, 0.81627], - [0.75536, 0.79977, 0.81588], - [0.76116, 0.80355, 0.81518], - [0.76672, 0.80712, 0.81417], - [0.77203, 0.81045, 0.81284], - [0.77708, 0.81354, 0.8112], - [0.78184, 0.81639, 0.80922], - [0.7863, 0.81896, 0.80691], - [0.79045, 0.82127, 0.80426], - [0.79429, 0.8233, 0.80127], - [0.7978, 0.82504, 0.79794], - [0.80098, 0.8265, 0.79428], - [0.8038, 0.82765, 0.79028], - [0.80628, 0.82851, 0.78595], - [0.80839, 0.82906, 0.78129], - [0.81014, 0.82929, 0.77631], - [0.81153, 0.82922, 0.77101], - [0.81253, 0.82883, 0.76541], - [0.81317, 0.82813, 0.7595], - [0.81344, 0.82712, 0.75332], - [0.81334, 0.8258, 0.74687], - [0.81288, 0.82418, 0.74015], - [0.81205, 0.82226, 0.73317], - [0.81087, 0.82004, 0.72597], - [0.80934, 0.81753, 0.71853], - [0.80746, 0.81474, 0.7109], - [0.80524, 0.81167, 0.70307], - [0.80271, 0.80833, 0.69506], - [0.79986, 0.80473, 0.68688], - [0.79669, 0.80088, 0.67856], - [0.79324, 0.79678, 0.6701], - [0.7895, 0.79245, 0.66152], - [0.78548, 0.7879, 0.65283], - [0.78121, 0.78312, 0.64404], - [0.77669, 0.77815, 0.63518], - [0.77192, 0.77297, 0.62625], - [0.76693, 0.76761, 0.61726], - [0.76173, 0.76207, 0.60824], - [0.75633, 0.75636, 0.59917], - [0.75074, 0.7505, 0.59007], - [0.74495, 0.74448, 0.58097], - [0.73902, 0.73832, 0.57187], - [0.73291, 0.73203, 0.56278], - [0.72666, 0.72562, 0.55368], - [0.72027, 0.71908, 0.54462], - [0.71376, 0.71244, 0.53558], - [0.70713, 0.7057, 0.5266], - [0.70038, 0.69887, 0.51764], - [0.69354, 0.69195, 0.50874], - [0.68661, 0.68495, 0.49988], - [0.67959, 0.67789, 0.49111], - [0.67251, 0.67075, 0.48238], - [0.66534, 0.66356, 0.47371], - [0.65813, 0.65631, 0.46513], - [0.65085, 0.64901, 0.45663], - [0.64352, 0.64166, 0.44821], - [0.63617, 0.63429, 0.43988], - [0.62877, 0.62688, 0.43163], - [0.62134, 0.61944, 0.42345], - [0.61388, 0.61197, 0.41538], - [0.60642, 0.6045, 0.40741], - [0.59893, 0.597, 0.39952], - [0.59144, 0.58948, 0.39174], - [0.58394, 0.58196, 0.38405], - [0.57645, 0.57444, 0.37648], - [0.56894, 0.56693, 0.36899], - [0.56146, 0.5594, 0.36161], - [0.55398, 0.55189, 0.35433], - [0.54652, 0.54437, 0.34717], - [0.53906, 0.53688, 0.3401], - [0.53164, 0.52939, 0.33314], - [0.52423, 0.52191, 0.32627], - [0.51686, 0.51447, 0.31955], - [0.50951, 0.50703, 0.31291], - [0.5022, 0.49962, 0.30641], - [0.49493, 0.49224, 0.29999], - [0.48769, 0.48488, 0.29369], - [0.48049, 0.47755, 0.28752], - [0.47333, 0.47026, 0.28147], - [0.46623, 0.46299, 0.27555], - [0.45918, 0.45577, 0.26973], - [0.45218, 0.44859, 0.26404], - [0.44523, 0.44144, 0.25845], - [0.43834, 0.43433, 0.25302], - [0.43152, 0.42729, 0.24771], - [0.42476, 0.42027, 0.24251], - [0.41806, 0.41332, 0.2375], - [0.41144, 0.40641, 0.23256], - [0.40488, 0.39955, 0.2278], - [0.39842, 0.39277, 0.22317], - [0.39203, 0.38603, 0.21868], - [0.38571, 0.37938, 0.21434], - [0.3795, 0.37278, 0.21015], - [0.37337, 0.36627, 0.20613], - [0.36733, 0.35981, 0.20222], - [0.3614, 0.35344, 0.19849], - [0.35557, 0.34715, 0.19495], - [0.34983, 0.34094, 0.19153], - [0.34418, 0.33483, 0.18832], - [0.33867, 0.32879, 0.18525], - [0.33328, 0.32285, 0.18231], - [0.32797, 0.317, 0.17959], - [0.32281, 0.31126, 0.17704], - [0.31775, 0.30563, 0.17466], - [0.31281, 0.30008, 0.17243], - [0.308, 0.29465, 0.1704], - [0.30332, 0.28935, 0.16854], - [0.29879, 0.28414, 0.16687], - [0.29436, 0.27908, 0.16532], - [0.29007, 0.27411, 0.16403], - [0.28591, 0.26928, 0.16286], - [0.28191, 0.26455, 0.16189], - [0.27802, 0.25997, 0.16107], - [0.27426, 0.25551, 0.16039], - [0.27065, 0.25118, 0.15992], - [0.26713, 0.24697, 0.15963], - [0.2638, 0.24289, 0.1595], - [0.26056, 0.23896, 0.15954], - [0.25747, 0.23519, 0.15973], - [0.25451, 0.23152, 0.16009], - [0.25167, 0.22798, 0.16064], - [0.24895, 0.22455, 0.16136], - [0.24634, 0.22132, 0.16219], - [0.24386, 0.2182, 0.16319], - [0.24152, 0.2152, 0.16434], - [0.23927, 0.21237, 0.1656], - [0.23716, 0.20964, 0.1671], - [0.23513, 0.20708, 0.16869], - [0.23318, 0.20464, 0.17044], - [0.23139, 0.20231, 0.17233], - [0.22964, 0.20014, 0.17439], - [0.22805, 0.19812, 0.17655], - [0.22652, 0.19626, 0.17891], - [0.22505, 0.19452, 0.18136], - [0.22371, 0.19288, 0.18399], - [0.22244, 0.1914, 0.18676], - [0.22126, 0.19007, 0.18967], - [0.22015, 0.18889, 0.19273], - [0.21911, 0.18786, 0.19593], - [0.21814, 0.18693, 0.19925], - [0.21724, 0.18619, 0.20275], - [0.21642, 0.1856, 0.20642], - [0.21564, 0.18513, 0.21018], - [0.21492, 0.18482, 0.21413], -]; - -export const colormap_buda_data: Array<[number, number, number]> = [ - [0.70015, 0.0027445, 0.70061], - [0.70019, 0.010833, 0.69719], - [0.70023, 0.019196, 0.69378], - [0.70026, 0.027497, 0.69041], - [0.70028, 0.036129, 0.68707], - [0.7003, 0.044535, 0.68375], - [0.70032, 0.052201, 0.68047], - [0.70033, 0.059479, 0.67723], - [0.70034, 0.066138, 0.67402], - [0.70035, 0.0725, 0.67086], - [0.70035, 0.078557, 0.66775], - [0.70036, 0.084489, 0.66466], - [0.70037, 0.090118, 0.66165], - [0.70038, 0.095602, 0.65866], - [0.70039, 0.10092, 0.65574], - [0.7004, 0.10618, 0.65285], - [0.70042, 0.11127, 0.65003], - [0.70045, 0.11628, 0.64726], - [0.70048, 0.12114, 0.64453], - [0.70052, 0.12603, 0.64186], - [0.70057, 0.13079, 0.63925], - [0.70064, 0.13546, 0.63668], - [0.70073, 0.14008, 0.63417], - [0.70083, 0.14469, 0.6317], - [0.70095, 0.14919, 0.62928], - [0.7011, 0.15364, 0.62692], - [0.70128, 0.15808, 0.62461], - [0.70149, 0.16247, 0.62235], - [0.70173, 0.1668, 0.62015], - [0.70201, 0.17108, 0.61798], - [0.70234, 0.17534, 0.61587], - [0.70271, 0.17955, 0.6138], - [0.70312, 0.18374, 0.61179], - [0.70358, 0.18794, 0.60982], - [0.70409, 0.19203, 0.60791], - [0.70466, 0.19615, 0.60603], - [0.70527, 0.2002, 0.60421], - [0.70595, 0.2043, 0.60242], - [0.70667, 0.20831, 0.60069], - [0.70744, 0.21233, 0.59899], - [0.70826, 0.21633, 0.59734], - [0.70914, 0.2203, 0.59571], - [0.71005, 0.22422, 0.59413], - [0.71101, 0.22819, 0.59259], - [0.71201, 0.2321, 0.59107], - [0.71304, 0.236, 0.58959], - [0.71411, 0.23986, 0.58813], - [0.71521, 0.24372, 0.58671], - [0.71634, 0.24759, 0.58531], - [0.71749, 0.25142, 0.58392], - [0.71864, 0.25523, 0.58256], - [0.71983, 0.25903, 0.58122], - [0.72101, 0.2628, 0.5799], - [0.72221, 0.26656, 0.57858], - [0.72342, 0.27032, 0.57728], - [0.72464, 0.27403, 0.57601], - [0.72586, 0.27775, 0.57472], - [0.72708, 0.28143, 0.57347], - [0.72829, 0.28511, 0.57222], - [0.72952, 0.28879, 0.57097], - [0.73073, 0.29243, 0.56973], - [0.73195, 0.29606, 0.5685], - [0.73316, 0.29969, 0.56729], - [0.73437, 0.30328, 0.56607], - [0.73557, 0.30688, 0.56485], - [0.73677, 0.31047, 0.56366], - [0.73796, 0.31402, 0.56246], - [0.73916, 0.31757, 0.56126], - [0.74035, 0.32111, 0.56008], - [0.74153, 0.32463, 0.55888], - [0.74271, 0.32815, 0.55771], - [0.74389, 0.33165, 0.55653], - [0.74506, 0.33517, 0.55536], - [0.74622, 0.33863, 0.5542], - [0.74739, 0.34211, 0.55303], - [0.74855, 0.34556, 0.55187], - [0.7497, 0.34902, 0.55071], - [0.75087, 0.35247, 0.54956], - [0.75202, 0.35591, 0.54842], - [0.75316, 0.35932, 0.54726], - [0.75431, 0.36274, 0.54612], - [0.75545, 0.36616, 0.54498], - [0.75659, 0.36956, 0.54384], - [0.75773, 0.37295, 0.54271], - [0.75886, 0.37635, 0.54156], - [0.75999, 0.37972, 0.54044], - [0.76112, 0.3831, 0.53931], - [0.76225, 0.38646, 0.53819], - [0.76337, 0.38982, 0.53706], - [0.7645, 0.39318, 0.53593], - [0.76562, 0.39653, 0.53482], - [0.76673, 0.39988, 0.53369], - [0.76785, 0.40323, 0.53259], - [0.76897, 0.40656, 0.53147], - [0.77008, 0.4099, 0.53036], - [0.7712, 0.41322, 0.52925], - [0.7723, 0.41654, 0.52814], - [0.77341, 0.41986, 0.52704], - [0.77451, 0.42317, 0.52593], - [0.77562, 0.42649, 0.52482], - [0.77673, 0.4298, 0.52372], - [0.77783, 0.4331, 0.52262], - [0.77892, 0.43641, 0.52152], - [0.78002, 0.43971, 0.52043], - [0.78111, 0.44302, 0.51934], - [0.7822, 0.44631, 0.51826], - [0.78329, 0.44961, 0.51717], - [0.78437, 0.45291, 0.51608], - [0.78545, 0.4562, 0.51501], - [0.78653, 0.4595, 0.51394], - [0.78759, 0.46279, 0.51286], - [0.78866, 0.4661, 0.5118], - [0.78971, 0.46941, 0.51074], - [0.79076, 0.4727, 0.5097], - [0.79181, 0.47602, 0.50866], - [0.79285, 0.47933, 0.50762], - [0.79388, 0.48264, 0.50659], - [0.79489, 0.48595, 0.50557], - [0.7959, 0.48927, 0.50457], - [0.7969, 0.49259, 0.50356], - [0.79789, 0.49592, 0.50257], - [0.79888, 0.49926, 0.5016], - [0.79985, 0.5026, 0.50062], - [0.80081, 0.50594, 0.49965], - [0.80176, 0.5093, 0.49871], - [0.80271, 0.51265, 0.49778], - [0.80364, 0.516, 0.49683], - [0.80457, 0.51938, 0.49591], - [0.80548, 0.52274, 0.495], - [0.8064, 0.52612, 0.49409], - [0.8073, 0.5295, 0.49318], - [0.80819, 0.53287, 0.49229], - [0.80908, 0.53625, 0.49142], - [0.80996, 0.53963, 0.49053], - [0.81084, 0.54303, 0.48964], - [0.81172, 0.54642, 0.48878], - [0.81258, 0.54981, 0.48792], - [0.81345, 0.5532, 0.48705], - [0.81431, 0.5566, 0.48618], - [0.81518, 0.56, 0.48532], - [0.81604, 0.56341, 0.48446], - [0.8169, 0.56681, 0.4836], - [0.81775, 0.5702, 0.48275], - [0.81861, 0.57361, 0.4819], - [0.81946, 0.57702, 0.48103], - [0.82032, 0.58043, 0.48019], - [0.82118, 0.58383, 0.47934], - [0.82204, 0.58724, 0.47848], - [0.82289, 0.59065, 0.47763], - [0.82374, 0.59407, 0.47677], - [0.8246, 0.59749, 0.47592], - [0.82545, 0.6009, 0.47508], - [0.82631, 0.60433, 0.47421], - [0.82717, 0.60775, 0.47335], - [0.82802, 0.61117, 0.4725], - [0.82888, 0.61459, 0.47165], - [0.82974, 0.61802, 0.4708], - [0.8306, 0.62145, 0.46994], - [0.83146, 0.62489, 0.46909], - [0.83232, 0.62832, 0.46822], - [0.83317, 0.63176, 0.46737], - [0.83404, 0.6352, 0.46651], - [0.8349, 0.63864, 0.46564], - [0.83576, 0.64209, 0.46479], - [0.83662, 0.64553, 0.46393], - [0.83749, 0.64899, 0.46306], - [0.83835, 0.65244, 0.4622], - [0.83921, 0.6559, 0.46134], - [0.84008, 0.65936, 0.46047], - [0.84095, 0.66283, 0.45961], - [0.84182, 0.66629, 0.45875], - [0.84268, 0.66976, 0.45788], - [0.84355, 0.67324, 0.45701], - [0.84442, 0.67671, 0.45615], - [0.84529, 0.68019, 0.45528], - [0.84616, 0.68368, 0.45442], - [0.84703, 0.68717, 0.45354], - [0.84791, 0.69065, 0.45268], - [0.84878, 0.69415, 0.4518], - [0.84966, 0.69765, 0.45092], - [0.85053, 0.70116, 0.45005], - [0.85141, 0.70467, 0.44918], - [0.8523, 0.70818, 0.4483], - [0.85317, 0.7117, 0.44741], - [0.85405, 0.71522, 0.44654], - [0.85494, 0.71874, 0.44566], - [0.85582, 0.72227, 0.44479], - [0.8567, 0.72581, 0.44391], - [0.85758, 0.72935, 0.44302], - [0.85847, 0.73289, 0.44214], - [0.85936, 0.73644, 0.44125], - [0.86025, 0.74, 0.44036], - [0.86114, 0.74355, 0.43947], - [0.86203, 0.74711, 0.43858], - [0.86292, 0.75068, 0.43771], - [0.86382, 0.75426, 0.43681], - [0.86471, 0.75783, 0.43592], - [0.8656, 0.76141, 0.43503], - [0.8665, 0.76501, 0.43412], - [0.8674, 0.76859, 0.43323], - [0.86831, 0.77219, 0.43234], - [0.86921, 0.7758, 0.43144], - [0.8701, 0.77941, 0.43054], - [0.87101, 0.78302, 0.42964], - [0.87192, 0.78665, 0.42873], - [0.87283, 0.79027, 0.42783], - [0.87374, 0.79391, 0.42693], - [0.87466, 0.79754, 0.42602], - [0.87558, 0.80119, 0.42512], - [0.8765, 0.80485, 0.4242], - [0.87744, 0.80851, 0.42329], - [0.87838, 0.81218, 0.42239], - [0.87933, 0.81586, 0.42148], - [0.8803, 0.81954, 0.42058], - [0.88128, 0.82324, 0.41968], - [0.88228, 0.82696, 0.41878], - [0.8833, 0.83068, 0.41788], - [0.88436, 0.83442, 0.41699], - [0.88544, 0.83817, 0.4161], - [0.88657, 0.84195, 0.41522], - [0.88774, 0.84574, 0.41435], - [0.88898, 0.84956, 0.4135], - [0.89027, 0.8534, 0.41266], - [0.89165, 0.85727, 0.41182], - [0.8931, 0.86118, 0.41101], - [0.89465, 0.86511, 0.41022], - [0.8963, 0.86908, 0.40944], - [0.89805, 0.87309, 0.40869], - [0.89994, 0.87713, 0.40798], - [0.90195, 0.88122, 0.40729], - [0.9041, 0.88535, 0.40663], - [0.9064, 0.88953, 0.40601], - [0.90885, 0.89375, 0.40542], - [0.91146, 0.89801, 0.40486], - [0.91422, 0.90232, 0.40435], - [0.91714, 0.90667, 0.40388], - [0.92022, 0.91107, 0.40344], - [0.92346, 0.9155, 0.40303], - [0.92684, 0.91998, 0.40266], - [0.93038, 0.92449, 0.40233], - [0.93405, 0.92904, 0.40204], - [0.93787, 0.93363, 0.40178], - [0.9418, 0.93824, 0.40155], - [0.94585, 0.94289, 0.40136], - [0.95, 0.94756, 0.40118], - [0.95426, 0.95224, 0.40103], - [0.9586, 0.95696, 0.4009], - [0.96301, 0.96169, 0.40079], - [0.9675, 0.96644, 0.40069], - [0.97205, 0.97121, 0.4006], - [0.97664, 0.97598, 0.40052], - [0.98129, 0.98078, 0.40045], - [0.98597, 0.98558, 0.40038], - [0.99068, 0.9904, 0.40032], - [0.99542, 0.99522, 0.40026], - [1, 1, 0.4002], -]; - -export const colormap_corc_data: Array<[number, number, number]> = [ - [0.171, 0.10033, 0.29984], - [0.1711, 0.10619, 0.30533], - [0.17113, 0.11194, 0.31082], - [0.17109, 0.11763, 0.31633], - [0.171, 0.12329, 0.32184], - [0.17084, 0.12895, 0.32738], - [0.17064, 0.13463, 0.33295], - [0.17039, 0.14021, 0.33851], - [0.17009, 0.14585, 0.34409], - [0.16976, 0.15141, 0.34971], - [0.16939, 0.15702, 0.35534], - [0.16898, 0.16264, 0.36096], - [0.16853, 0.16822, 0.36662], - [0.16806, 0.17384, 0.37228], - [0.1676, 0.17947, 0.37797], - [0.16714, 0.18513, 0.38368], - [0.16665, 0.19077, 0.38939], - [0.16614, 0.19648, 0.39513], - [0.16565, 0.20215, 0.40089], - [0.16519, 0.2079, 0.40665], - [0.16478, 0.21365, 0.41243], - [0.16441, 0.21945, 0.41822], - [0.16407, 0.22525, 0.42403], - [0.16377, 0.23111, 0.42986], - [0.16355, 0.23701, 0.4357], - [0.16341, 0.2429, 0.44155], - [0.16337, 0.24888, 0.4474], - [0.16345, 0.25488, 0.45327], - [0.16367, 0.2609, 0.45915], - [0.16404, 0.26697, 0.46502], - [0.16456, 0.2731, 0.47091], - [0.16525, 0.27926, 0.47678], - [0.16622, 0.28544, 0.48265], - [0.16742, 0.29171, 0.48852], - [0.16886, 0.29798, 0.49438], - [0.17055, 0.30431, 0.5002], - [0.17253, 0.31069, 0.50602], - [0.17486, 0.31708, 0.51181], - [0.17748, 0.32352, 0.51758], - [0.1804, 0.33, 0.52331], - [0.18368, 0.33649, 0.529], - [0.18732, 0.34303, 0.53464], - [0.19125, 0.34957, 0.54024], - [0.19555, 0.35615, 0.5458], - [0.20015, 0.36273, 0.5513], - [0.20511, 0.36934, 0.55674], - [0.21036, 0.37595, 0.56213], - [0.21591, 0.38257, 0.56746], - [0.22171, 0.3892, 0.57273], - [0.2278, 0.39583, 0.57793], - [0.23411, 0.40244, 0.58309], - [0.24065, 0.40907, 0.58818], - [0.24742, 0.41569, 0.59323], - [0.25438, 0.42229, 0.59821], - [0.26149, 0.42891, 0.60315], - [0.26878, 0.43552, 0.60805], - [0.2762, 0.44211, 0.61288], - [0.28373, 0.4487, 0.61769], - [0.29141, 0.45527, 0.62245], - [0.29918, 0.46185, 0.62719], - [0.30703, 0.46841, 0.63189], - [0.31496, 0.47499, 0.63657], - [0.32299, 0.48154, 0.64121], - [0.33106, 0.48811, 0.64585], - [0.33922, 0.49467, 0.65047], - [0.34741, 0.50123, 0.65507], - [0.35565, 0.50779, 0.65966], - [0.36392, 0.51435, 0.66424], - [0.37224, 0.52091, 0.66882], - [0.38061, 0.52747, 0.67339], - [0.389, 0.53404, 0.67795], - [0.39741, 0.54062, 0.68251], - [0.40587, 0.54719, 0.68707], - [0.41434, 0.55377, 0.69164], - [0.42283, 0.56037, 0.6962], - [0.43136, 0.56696, 0.70076], - [0.4399, 0.57356, 0.70533], - [0.44846, 0.58017, 0.7099], - [0.45704, 0.58678, 0.71447], - [0.46563, 0.5934, 0.71905], - [0.47426, 0.60003, 0.72363], - [0.48289, 0.60666, 0.72822], - [0.49155, 0.6133, 0.73282], - [0.50021, 0.61996, 0.73741], - [0.5089, 0.62661, 0.74201], - [0.5176, 0.63327, 0.74661], - [0.52632, 0.63994, 0.75123], - [0.53504, 0.64662, 0.75584], - [0.54379, 0.6533, 0.76046], - [0.55255, 0.66, 0.76509], - [0.56132, 0.66669, 0.76971], - [0.5701, 0.6734, 0.77435], - [0.57891, 0.68011, 0.77899], - [0.58771, 0.68684, 0.78364], - [0.59655, 0.69357, 0.78829], - [0.60538, 0.7003, 0.79294], - [0.61423, 0.70705, 0.79759], - [0.6231, 0.7138, 0.80225], - [0.63197, 0.72056, 0.80692], - [0.64085, 0.72732, 0.81158], - [0.64975, 0.73409, 0.81624], - [0.65864, 0.74087, 0.8209], - [0.66755, 0.74765, 0.82555], - [0.67646, 0.75444, 0.8302], - [0.68537, 0.76123, 0.83483], - [0.69427, 0.76801, 0.83945], - [0.70318, 0.77481, 0.84404], - [0.71207, 0.7816, 0.8486], - [0.72094, 0.78839, 0.85313], - [0.72979, 0.79517, 0.85761], - [0.7386, 0.80193, 0.86203], - [0.74737, 0.80869, 0.86637], - [0.75608, 0.81541, 0.87061], - [0.76471, 0.82211, 0.87475], - [0.77323, 0.82877, 0.87874], - [0.78164, 0.83536, 0.88257], - [0.78989, 0.84189, 0.8862], - [0.79795, 0.84833, 0.88958], - [0.80578, 0.85465, 0.89269], - [0.81332, 0.86082, 0.89547], - [0.82051, 0.86681, 0.89787], - [0.82731, 0.87258, 0.89985], - [0.83362, 0.87808, 0.90133], - [0.83938, 0.88326, 0.90228], - [0.8445, 0.88806, 0.90264], - [0.84892, 0.89244, 0.90237], - [0.85255, 0.89633, 0.90142], - [0.85534, 0.89968, 0.89979], - [0.85724, 0.90245, 0.89746], - [0.85821, 0.9046, 0.89443], - [0.85826, 0.90613, 0.89074], - [0.85738, 0.90702, 0.88641], - [0.85562, 0.90728, 0.88151], - [0.85301, 0.90693, 0.87608], - [0.84962, 0.90601, 0.87019], - [0.84552, 0.90455, 0.86392], - [0.84079, 0.90262, 0.8573], - [0.8355, 0.90026, 0.85043], - [0.82974, 0.89751, 0.84333], - [0.82355, 0.89444, 0.83606], - [0.81703, 0.89108, 0.82865], - [0.81021, 0.88747, 0.82114], - [0.80315, 0.88367, 0.81355], - [0.79589, 0.87969, 0.8059], - [0.78847, 0.87557, 0.79821], - [0.78091, 0.87133, 0.79049], - [0.77325, 0.86699, 0.78275], - [0.76551, 0.86258, 0.775], - [0.7577, 0.8581, 0.76724], - [0.74983, 0.85357, 0.75948], - [0.74193, 0.84901, 0.75173], - [0.73401, 0.84442, 0.74397], - [0.72606, 0.8398, 0.73621], - [0.71809, 0.83516, 0.72847], - [0.71012, 0.83052, 0.72073], - [0.70214, 0.82586, 0.71299], - [0.69416, 0.8212, 0.70527], - [0.6862, 0.81654, 0.69756], - [0.67823, 0.81187, 0.68986], - [0.67027, 0.80721, 0.68216], - [0.66231, 0.80254, 0.67447], - [0.65435, 0.79788, 0.66679], - [0.64641, 0.79323, 0.65913], - [0.63848, 0.78858, 0.65148], - [0.63056, 0.78393, 0.64382], - [0.62265, 0.77928, 0.63619], - [0.61474, 0.77464, 0.62855], - [0.60686, 0.77001, 0.62093], - [0.59897, 0.76538, 0.6133], - [0.59109, 0.76075, 0.6057], - [0.58323, 0.75613, 0.5981], - [0.57538, 0.75151, 0.5905], - [0.56753, 0.74689, 0.58292], - [0.5597, 0.74228, 0.57534], - [0.55187, 0.73766, 0.56776], - [0.54405, 0.73306, 0.5602], - [0.53624, 0.72845, 0.55263], - [0.52844, 0.72384, 0.54506], - [0.52064, 0.71923, 0.53751], - [0.51286, 0.71462, 0.52994], - [0.50508, 0.71001, 0.52237], - [0.49731, 0.70539, 0.51482], - [0.48954, 0.70077, 0.50725], - [0.48179, 0.69614, 0.49967], - [0.47404, 0.69149, 0.4921], - [0.46629, 0.68683, 0.4845], - [0.45856, 0.68215, 0.4769], - [0.45084, 0.67746, 0.46929], - [0.44313, 0.67274, 0.46164], - [0.43544, 0.66799, 0.45397], - [0.42775, 0.6632, 0.44627], - [0.42007, 0.65836, 0.43854], - [0.41243, 0.65348, 0.43077], - [0.40479, 0.64854, 0.42295], - [0.3972, 0.64354, 0.41508], - [0.38964, 0.63847, 0.40716], - [0.38212, 0.63332, 0.39917], - [0.37467, 0.62808, 0.39113], - [0.36726, 0.62275, 0.383], - [0.35994, 0.61731, 0.3748], - [0.35271, 0.61176, 0.36654], - [0.34559, 0.60608, 0.35818], - [0.3386, 0.6003, 0.34976], - [0.33175, 0.59439, 0.34127], - [0.32508, 0.58835, 0.33272], - [0.31862, 0.5822, 0.3241], - [0.31236, 0.57594, 0.31546], - [0.30639, 0.56955, 0.30678], - [0.30064, 0.56307, 0.29808], - [0.29522, 0.5565, 0.28942], - [0.29011, 0.54986, 0.28076], - [0.28533, 0.54316, 0.27217], - [0.2809, 0.53642, 0.26369], - [0.27686, 0.52965, 0.25527], - [0.27316, 0.52289, 0.24696], - [0.26983, 0.51612, 0.2388], - [0.26683, 0.50941, 0.2308], - [0.26421, 0.50273, 0.22297], - [0.26191, 0.49611, 0.21528], - [0.25993, 0.48956, 0.20781], - [0.25824, 0.4831, 0.20049], - [0.25684, 0.47672, 0.19341], - [0.25568, 0.47044, 0.18649], - [0.25478, 0.46425, 0.17975], - [0.25405, 0.45813, 0.17319], - [0.25351, 0.45214, 0.16682], - [0.25314, 0.44621, 0.16055], - [0.25291, 0.44039, 0.15448], - [0.25281, 0.43466, 0.14853], - [0.2528, 0.429, 0.14275], - [0.25289, 0.42342, 0.13706], - [0.25306, 0.41793, 0.13148], - [0.25328, 0.41252, 0.12601], - [0.25356, 0.40715, 0.12057], - [0.25388, 0.40185, 0.11527], - [0.25423, 0.39662, 0.11008], - [0.25462, 0.39145, 0.10481], - [0.25501, 0.38631, 0.09971], - [0.25541, 0.38126, 0.09467], - [0.25581, 0.37623, 0.089581], - [0.25622, 0.37124, 0.084565], - [0.25664, 0.36632, 0.079479], - [0.25706, 0.36141, 0.074491], - [0.25746, 0.35656, 0.069524], - [0.25784, 0.35172, 0.064405], - [0.25821, 0.34695, 0.059366], - [0.25858, 0.34218, 0.05412], - [0.25893, 0.33745, 0.049005], - [0.25924, 0.33276, 0.043542], - [0.25953, 0.32806, 0.038204], - [0.25979, 0.32341, 0.032741], - [0.26002, 0.31877, 0.027725], - [0.26021, 0.31415, 0.022967], - [0.26037, 0.30955, 0.01845], - [0.2605, 0.30495, 0.014165], - [0.26058, 0.30036, 0.0098945], -]; - -export const colormap_corco_data: Array<[number, number, number]> = [ - [0.24651, 0.24352, 0.2292], - [0.24607, 0.24243, 0.23232], - [0.24564, 0.24145, 0.23554], - [0.24522, 0.24052, 0.23883], - [0.24481, 0.23974, 0.24225], - [0.24441, 0.23905, 0.24576], - [0.24402, 0.23847, 0.2494], - [0.24365, 0.23802, 0.25316], - [0.24329, 0.23769, 0.25703], - [0.24295, 0.23749, 0.26102], - [0.24264, 0.23741, 0.26513], - [0.24235, 0.23747, 0.2694], - [0.24209, 0.23767, 0.27379], - [0.24185, 0.23802, 0.27831], - [0.24164, 0.23852, 0.28299], - [0.24147, 0.23921, 0.2878], - [0.24133, 0.24005, 0.29278], - [0.24123, 0.24109, 0.29791], - [0.24118, 0.24229, 0.30319], - [0.24118, 0.24368, 0.30866], - [0.24123, 0.24527, 0.31425], - [0.24135, 0.24707, 0.32003], - [0.24152, 0.24906, 0.32594], - [0.24176, 0.25127, 0.33205], - [0.24207, 0.25367, 0.33828], - [0.24246, 0.25627, 0.34469], - [0.24293, 0.25913, 0.35124], - [0.2435, 0.26218, 0.35795], - [0.24417, 0.26544, 0.36478], - [0.24494, 0.26895, 0.37175], - [0.24582, 0.27263, 0.37886], - [0.24683, 0.27657, 0.38607], - [0.24797, 0.28067, 0.39341], - [0.24921, 0.28501, 0.40086], - [0.25059, 0.28956, 0.40836], - [0.25214, 0.29428, 0.41596], - [0.25383, 0.29922, 0.42362], - [0.25567, 0.30432, 0.43135], - [0.25767, 0.30961, 0.43909], - [0.25986, 0.31504, 0.44689], - [0.26221, 0.32066, 0.4547], - [0.26473, 0.32639, 0.46249], - [0.26743, 0.3323, 0.47031], - [0.27036, 0.33831, 0.47809], - [0.27343, 0.34444, 0.48584], - [0.2767, 0.35071, 0.49355], - [0.28015, 0.35705, 0.50123], - [0.2838, 0.36348, 0.50884], - [0.28763, 0.36999, 0.51637], - [0.29167, 0.37659, 0.52384], - [0.29586, 0.38324, 0.53123], - [0.30024, 0.38994, 0.53854], - [0.3048, 0.39669, 0.54575], - [0.30955, 0.40349, 0.55287], - [0.31442, 0.41032, 0.55989], - [0.31949, 0.41717, 0.56681], - [0.32469, 0.42404, 0.57363], - [0.33007, 0.43093, 0.58034], - [0.33558, 0.43784, 0.58695], - [0.34122, 0.44474, 0.59345], - [0.347, 0.45164, 0.59985], - [0.3529, 0.45854, 0.60614], - [0.35891, 0.46544, 0.61233], - [0.36505, 0.47234, 0.61843], - [0.37128, 0.47923, 0.62442], - [0.37763, 0.48609, 0.63031], - [0.38406, 0.49295, 0.6361], - [0.39058, 0.49979, 0.64179], - [0.39718, 0.50662, 0.64739], - [0.40387, 0.51343, 0.65289], - [0.41063, 0.52021, 0.65831], - [0.41745, 0.52699, 0.66363], - [0.42432, 0.53373, 0.66887], - [0.43126, 0.54046, 0.67401], - [0.43824, 0.54716, 0.67907], - [0.44526, 0.55384, 0.68404], - [0.45234, 0.5605, 0.68893], - [0.45943, 0.56714, 0.69372], - [0.46656, 0.57374, 0.69844], - [0.4737, 0.58032, 0.70307], - [0.48087, 0.58686, 0.70761], - [0.48806, 0.59339, 0.71206], - [0.49525, 0.59988, 0.71643], - [0.50243, 0.60634, 0.72069], - [0.50961, 0.61277, 0.72487], - [0.51679, 0.61917, 0.72895], - [0.52394, 0.62553, 0.73294], - [0.53106, 0.63185, 0.73681], - [0.53817, 0.63813, 0.74059], - [0.54522, 0.64436, 0.74425], - [0.55224, 0.65056, 0.74781], - [0.55919, 0.65671, 0.75124], - [0.56609, 0.6628, 0.75455], - [0.57292, 0.66883, 0.75772], - [0.57967, 0.6748, 0.76076], - [0.58632, 0.68071, 0.76366], - [0.59289, 0.68655, 0.76641], - [0.59934, 0.69232, 0.769], - [0.60566, 0.698, 0.77143], - [0.61187, 0.7036, 0.77368], - [0.61793, 0.70911, 0.77576], - [0.62384, 0.7145, 0.77766], - [0.62958, 0.7198, 0.77935], - [0.63514, 0.72498, 0.78084], - [0.64052, 0.73004, 0.78213], - [0.64568, 0.73497, 0.78319], - [0.65064, 0.73976, 0.78403], - [0.65536, 0.74439, 0.78463], - [0.65985, 0.74887, 0.78499], - [0.66407, 0.75319, 0.78511], - [0.66804, 0.75733, 0.78497], - [0.67172, 0.76129, 0.78457], - [0.67512, 0.76506, 0.7839], - [0.67822, 0.76862, 0.78296], - [0.681, 0.77199, 0.78176], - [0.68348, 0.77513, 0.78028], - [0.68563, 0.77806, 0.77853], - [0.68744, 0.78075, 0.7765], - [0.68892, 0.78321, 0.77419], - [0.69005, 0.78543, 0.77162], - [0.69084, 0.7874, 0.76877], - [0.69128, 0.78913, 0.76566], - [0.69138, 0.79061, 0.76228], - [0.69113, 0.79184, 0.75865], - [0.69054, 0.79281, 0.75476], - [0.68962, 0.79354, 0.75063], - [0.68836, 0.79401, 0.74626], - [0.68676, 0.79423, 0.74166], - [0.68485, 0.7942, 0.73685], - [0.68262, 0.79393, 0.73183], - [0.68008, 0.79342, 0.7266], - [0.67727, 0.79267, 0.72118], - [0.67415, 0.79169, 0.71559], - [0.67077, 0.79049, 0.70981], - [0.66712, 0.78907, 0.70387], - [0.66324, 0.78743, 0.69778], - [0.6591, 0.78559, 0.69154], - [0.65474, 0.78355, 0.68517], - [0.65017, 0.78131, 0.67867], - [0.64539, 0.77888, 0.67205], - [0.64043, 0.77628, 0.66532], - [0.63528, 0.7735, 0.65848], - [0.62998, 0.77056, 0.65155], - [0.62451, 0.76745, 0.64451], - [0.61891, 0.76419, 0.6374], - [0.61315, 0.76078, 0.6302], - [0.6073, 0.75722, 0.62293], - [0.60131, 0.75352, 0.61558], - [0.59523, 0.74969, 0.60817], - [0.58904, 0.74573, 0.60069], - [0.58278, 0.74164, 0.59315], - [0.57645, 0.73743, 0.58556], - [0.57002, 0.73311, 0.5779], - [0.56356, 0.72866, 0.5702], - [0.55703, 0.72411, 0.56246], - [0.55045, 0.71944, 0.55465], - [0.54383, 0.71466, 0.54681], - [0.53719, 0.70979, 0.53892], - [0.53051, 0.7048, 0.53099], - [0.52381, 0.69972, 0.52302], - [0.5171, 0.69453, 0.51501], - [0.51038, 0.68926, 0.50697], - [0.50366, 0.68387, 0.4989], - [0.49694, 0.6784, 0.4908], - [0.49024, 0.67284, 0.48266], - [0.48354, 0.66717, 0.47451], - [0.47688, 0.66142, 0.46632], - [0.47024, 0.65557, 0.45813], - [0.46363, 0.64965, 0.44992], - [0.45706, 0.64362, 0.4417], - [0.45054, 0.63752, 0.43346], - [0.44407, 0.63134, 0.42525], - [0.43766, 0.62507, 0.41702], - [0.4313, 0.61874, 0.40881], - [0.42502, 0.61231, 0.40062], - [0.4188, 0.60582, 0.39243], - [0.41269, 0.59928, 0.38429], - [0.40664, 0.59266, 0.3762], - [0.4007, 0.58599, 0.36814], - [0.39484, 0.57926, 0.36013], - [0.3891, 0.57248, 0.35219], - [0.38347, 0.56565, 0.34432], - [0.37794, 0.55879, 0.33653], - [0.37254, 0.55192, 0.32885], - [0.36726, 0.545, 0.32125], - [0.36212, 0.53808, 0.31377], - [0.35711, 0.53113, 0.30642], - [0.35222, 0.52419, 0.29918], - [0.3475, 0.51725, 0.29209], - [0.3429, 0.51032, 0.28513], - [0.33844, 0.50341, 0.27837], - [0.33415, 0.49653, 0.27174], - [0.33, 0.48969, 0.26533], - [0.32598, 0.48289, 0.2591], - [0.32214, 0.47614, 0.25304], - [0.31843, 0.46946, 0.24719], - [0.31487, 0.46281, 0.24156], - [0.31147, 0.45626, 0.23614], - [0.30822, 0.44978, 0.23093], - [0.30511, 0.44338, 0.22597], - [0.30213, 0.43708, 0.22122], - [0.29932, 0.43086, 0.21671], - [0.29663, 0.42474, 0.21242], - [0.29405, 0.41872, 0.20837], - [0.29164, 0.41283, 0.20457], - [0.28934, 0.40702, 0.20097], - [0.28714, 0.40134, 0.19765], - [0.28507, 0.39577, 0.19457], - [0.28314, 0.3903, 0.19167], - [0.28128, 0.38496, 0.18903], - [0.27955, 0.37974, 0.18661], - [0.2779, 0.37465, 0.18441], - [0.27636, 0.36966, 0.18241], - [0.27487, 0.36479, 0.18063], - [0.27351, 0.36004, 0.17908], - [0.27218, 0.35543, 0.17773], - [0.27097, 0.35091, 0.17651], - [0.26982, 0.34649, 0.17553], - [0.26872, 0.34221, 0.17474], - [0.26766, 0.33802, 0.17409], - [0.2667, 0.33396, 0.17361], - [0.26578, 0.32999, 0.1733], - [0.26489, 0.32611, 0.17314], - [0.26408, 0.32237, 0.17313], - [0.26329, 0.3187, 0.17327], - [0.26252, 0.31513, 0.17354], - [0.2618, 0.31165, 0.17394], - [0.26111, 0.30827, 0.17448], - [0.26046, 0.30499, 0.17512], - [0.25983, 0.30177, 0.17584], - [0.25922, 0.29866, 0.17672], - [0.25862, 0.29562, 0.17773], - [0.25804, 0.29267, 0.17879], - [0.25749, 0.28979, 0.17994], - [0.25696, 0.28698, 0.18119], - [0.25642, 0.28427, 0.18254], - [0.2559, 0.28162, 0.184], - [0.25541, 0.27906, 0.18555], - [0.25492, 0.27655, 0.18714], - [0.25442, 0.27411, 0.18883], - [0.25393, 0.27173, 0.19058], - [0.25345, 0.26946, 0.19242], - [0.25297, 0.2672, 0.19437], - [0.2525, 0.26505, 0.19635], - [0.25203, 0.26297, 0.19839], - [0.25156, 0.26095, 0.20052], - [0.25109, 0.259, 0.20275], - [0.25061, 0.25711, 0.20504], - [0.25014, 0.25531, 0.20742], - [0.24968, 0.25356, 0.20985], - [0.24923, 0.2519, 0.21238], - [0.24878, 0.25028, 0.21495], - [0.24833, 0.24879, 0.21765], - [0.24787, 0.24734, 0.22042], - [0.24741, 0.24598, 0.22326], - [0.24696, 0.2447, 0.2262], -]; - -export const colormap_davos_data: Array<[number, number, number]> = [ - [0, 0.019685, 0.29201], - [0, 0.027123, 0.29748], - [0, 0.034324, 0.30295], - [0.00076962, 0.041437, 0.30847], - [0.0023129, 0.047559, 0.314], - [0.0043894, 0.053102, 0.31954], - [0.0066067, 0.058541, 0.32508], - [0.0088746, 0.063928, 0.33063], - [0.011304, 0.069327, 0.33618], - [0.013761, 0.074551, 0.34174], - [0.01619, 0.079806, 0.3473], - [0.01868, 0.085081, 0.35284], - [0.021233, 0.090352, 0.35838], - [0.023852, 0.095588, 0.36391], - [0.02654, 0.10079, 0.36945], - [0.029301, 0.10606, 0.37496], - [0.032137, 0.11127, 0.38047], - [0.035259, 0.11648, 0.38595], - [0.03825, 0.12165, 0.39144], - [0.041347, 0.12687, 0.39688], - [0.044338, 0.13212, 0.40232], - [0.047327, 0.13734, 0.40774], - [0.050291, 0.14254, 0.41314], - [0.053198, 0.14777, 0.4185], - [0.056204, 0.15296, 0.42383], - [0.05913, 0.15821, 0.42915], - [0.06198, 0.16344, 0.43442], - [0.06489, 0.16864, 0.43966], - [0.067805, 0.17386, 0.44487], - [0.070681, 0.17908, 0.45002], - [0.073639, 0.1843, 0.45515], - [0.076446, 0.18952, 0.46021], - [0.07937, 0.19476, 0.46524], - [0.082366, 0.19994, 0.47023], - [0.085246, 0.20517, 0.47517], - [0.088241, 0.21038, 0.48004], - [0.091235, 0.21558, 0.48485], - [0.094218, 0.2208, 0.48961], - [0.097192, 0.22598, 0.49432], - [0.10023, 0.23115, 0.49896], - [0.10333, 0.23632, 0.50353], - [0.10643, 0.24147, 0.50804], - [0.10953, 0.2466, 0.51247], - [0.11265, 0.25175, 0.51684], - [0.1158, 0.25686, 0.52112], - [0.11898, 0.26195, 0.52533], - [0.12214, 0.26702, 0.52947], - [0.12542, 0.27208, 0.53351], - [0.12867, 0.27714, 0.53749], - [0.13198, 0.28216, 0.54136], - [0.1353, 0.28713, 0.54517], - [0.13865, 0.29211, 0.54888], - [0.14202, 0.29706, 0.5525], - [0.14545, 0.30195, 0.55601], - [0.14883, 0.30685, 0.55945], - [0.15228, 0.31168, 0.56279], - [0.15579, 0.31652, 0.56602], - [0.15927, 0.3213, 0.56916], - [0.16281, 0.32604, 0.57221], - [0.16635, 0.33076, 0.57515], - [0.16993, 0.33545, 0.57799], - [0.17351, 0.34008, 0.58073], - [0.17713, 0.34467, 0.58337], - [0.18074, 0.34923, 0.58591], - [0.18441, 0.35374, 0.58833], - [0.1881, 0.35821, 0.59066], - [0.19176, 0.36264, 0.59289], - [0.19546, 0.36702, 0.595], - [0.19916, 0.37135, 0.59702], - [0.20291, 0.37564, 0.59892], - [0.20668, 0.37989, 0.60073], - [0.21041, 0.38408, 0.60243], - [0.21418, 0.38823, 0.60403], - [0.21795, 0.39233, 0.60552], - [0.22173, 0.39638, 0.60692], - [0.22553, 0.40038, 0.60821], - [0.22931, 0.40432, 0.6094], - [0.23311, 0.40823, 0.61049], - [0.23695, 0.41208, 0.61149], - [0.24073, 0.41588, 0.61238], - [0.24454, 0.41964, 0.61318], - [0.24839, 0.42333, 0.61388], - [0.2522, 0.42699, 0.6145], - [0.256, 0.43059, 0.61502], - [0.25984, 0.43414, 0.61546], - [0.26367, 0.43766, 0.61581], - [0.26745, 0.44111, 0.61607], - [0.27128, 0.44454, 0.61624], - [0.2751, 0.44789, 0.61633], - [0.27892, 0.45122, 0.61635], - [0.28273, 0.4545, 0.61628], - [0.2865, 0.45772, 0.61613], - [0.29031, 0.46091, 0.61591], - [0.2941, 0.46407, 0.61562], - [0.29789, 0.46717, 0.61525], - [0.30167, 0.47023, 0.61482], - [0.30547, 0.47324, 0.61432], - [0.30924, 0.47623, 0.61375], - [0.31299, 0.47918, 0.61312], - [0.31676, 0.48209, 0.61244], - [0.32052, 0.48496, 0.6117], - [0.32425, 0.48781, 0.6109], - [0.32799, 0.49062, 0.61003], - [0.33172, 0.49338, 0.60913], - [0.33546, 0.49612, 0.60817], - [0.33918, 0.49885, 0.60716], - [0.3429, 0.50154, 0.6061], - [0.34659, 0.5042, 0.605], - [0.3503, 0.50682, 0.60387], - [0.35399, 0.50943, 0.60268], - [0.3577, 0.51201, 0.60146], - [0.36137, 0.51458, 0.60021], - [0.36505, 0.51712, 0.59892], - [0.36873, 0.51964, 0.5976], - [0.37239, 0.52214, 0.59624], - [0.37607, 0.52463, 0.59486], - [0.37973, 0.5271, 0.59346], - [0.38339, 0.52956, 0.59203], - [0.38704, 0.532, 0.59056], - [0.3907, 0.53443, 0.58908], - [0.39435, 0.53685, 0.58759], - [0.39801, 0.53925, 0.58608], - [0.40165, 0.54165, 0.58455], - [0.40531, 0.54405, 0.583], - [0.40896, 0.54645, 0.58144], - [0.41262, 0.54884, 0.57988], - [0.41627, 0.55121, 0.5783], - [0.41992, 0.55359, 0.57672], - [0.42358, 0.55597, 0.57512], - [0.42725, 0.55835, 0.57353], - [0.43092, 0.56074, 0.57194], - [0.43459, 0.56313, 0.57033], - [0.43828, 0.56552, 0.56874], - [0.44197, 0.56792, 0.56715], - [0.44565, 0.57032, 0.56556], - [0.44937, 0.57275, 0.56398], - [0.45309, 0.57517, 0.56241], - [0.45681, 0.57761, 0.56084], - [0.46055, 0.58007, 0.55929], - [0.46433, 0.58253, 0.55775], - [0.46809, 0.58503, 0.55622], - [0.47189, 0.58752, 0.55473], - [0.4757, 0.59004, 0.55324], - [0.47953, 0.5926, 0.55178], - [0.48338, 0.59516, 0.55034], - [0.48726, 0.59776, 0.54894], - [0.49117, 0.60038, 0.54755], - [0.49509, 0.60303, 0.5462], - [0.49905, 0.60571, 0.54488], - [0.50303, 0.60843, 0.5436], - [0.50706, 0.61118, 0.54236], - [0.51112, 0.61395, 0.54116], - [0.51522, 0.61678, 0.54], - [0.51937, 0.61965, 0.53891], - [0.52355, 0.62255, 0.53786], - [0.52777, 0.62551, 0.53686], - [0.53206, 0.62851, 0.53591], - [0.53639, 0.63156, 0.53503], - [0.54077, 0.63467, 0.53422], - [0.54521, 0.63783, 0.53348], - [0.54971, 0.64104, 0.53282], - [0.55428, 0.64432, 0.53224], - [0.55891, 0.64767, 0.53174], - [0.56362, 0.65108, 0.53132], - [0.56839, 0.65456, 0.531], - [0.57326, 0.65811, 0.53079], - [0.57819, 0.66174, 0.53067], - [0.58321, 0.66544, 0.53067], - [0.58832, 0.66922, 0.53078], - [0.59353, 0.67309, 0.53102], - [0.59882, 0.67705, 0.53139], - [0.60422, 0.68107, 0.53189], - [0.60972, 0.68521, 0.53254], - [0.61531, 0.68944, 0.53332], - [0.62103, 0.69375, 0.53427], - [0.62684, 0.69816, 0.53539], - [0.63277, 0.70268, 0.53668], - [0.63881, 0.70728, 0.53814], - [0.64497, 0.71199, 0.53977], - [0.65125, 0.71681, 0.5416], - [0.65764, 0.72171, 0.54364], - [0.66413, 0.72672, 0.54587], - [0.67075, 0.73183, 0.54832], - [0.67748, 0.73703, 0.55097], - [0.68431, 0.74232, 0.55384], - [0.69125, 0.74771, 0.55694], - [0.6983, 0.75318, 0.56026], - [0.70544, 0.75873, 0.56382], - [0.71266, 0.76436, 0.5676], - [0.71998, 0.77006, 0.57162], - [0.72736, 0.77583, 0.57587], - [0.73481, 0.78165, 0.58035], - [0.74231, 0.78751, 0.58506], - [0.74985, 0.79342, 0.58999], - [0.75743, 0.79936, 0.59516], - [0.76503, 0.80531, 0.60053], - [0.77263, 0.81128, 0.60612], - [0.78022, 0.81724, 0.61191], - [0.7878, 0.82319, 0.61789], - [0.79534, 0.82912, 0.62406], - [0.80283, 0.83501, 0.6304], - [0.81025, 0.84085, 0.63691], - [0.81761, 0.84664, 0.64355], - [0.82487, 0.85237, 0.65035], - [0.83203, 0.85801, 0.65727], - [0.83907, 0.86357, 0.66429], - [0.84598, 0.86903, 0.67142], - [0.85276, 0.87439, 0.67863], - [0.85938, 0.87963, 0.68592], - [0.86585, 0.88476, 0.69326], - [0.87216, 0.88977, 0.70066], - [0.87829, 0.89464, 0.70808], - [0.88424, 0.89938, 0.71554], - [0.89001, 0.90397, 0.72299], - [0.89559, 0.90844, 0.73047], - [0.90099, 0.91275, 0.73792], - [0.90619, 0.91692, 0.74537], - [0.9112, 0.92095, 0.75278], - [0.91602, 0.92483, 0.76018], - [0.92065, 0.92857, 0.76753], - [0.92509, 0.93217, 0.77484], - [0.92935, 0.93564, 0.78211], - [0.93342, 0.93896, 0.78932], - [0.93732, 0.94215, 0.79647], - [0.94103, 0.94521, 0.80357], - [0.94458, 0.94814, 0.81061], - [0.94796, 0.95096, 0.81759], - [0.95118, 0.95365, 0.82451], - [0.95425, 0.95622, 0.83137], - [0.95716, 0.95869, 0.83816], - [0.95993, 0.96104, 0.84489], - [0.96256, 0.9633, 0.85156], - [0.96506, 0.96546, 0.85817], - [0.96743, 0.96753, 0.86472], - [0.96967, 0.9695, 0.87121], - [0.97181, 0.9714, 0.87765], - [0.97382, 0.97321, 0.88403], - [0.97573, 0.97495, 0.89036], - [0.97755, 0.97662, 0.89664], - [0.97927, 0.97822, 0.90287], - [0.98089, 0.97976, 0.90905], - [0.98244, 0.98124, 0.91519], - [0.9839, 0.98267, 0.9213], - [0.98528, 0.98404, 0.92736], - [0.9866, 0.98537, 0.93338], - [0.98784, 0.98665, 0.93938], - [0.98903, 0.98789, 0.94534], - [0.99015, 0.9891, 0.95127], - [0.99123, 0.99027, 0.95718], - [0.99225, 0.99141, 0.96306], - [0.99323, 0.99252, 0.96892], - [0.99415, 0.99361, 0.97476], - [0.99505, 0.99467, 0.98059], - [0.9959, 0.99572, 0.98641], - [0.99673, 0.99675, 0.9922], - [0.99752, 0.99776, 0.99799], -]; - -export const colormap_devon_data: Array<[number, number, number]> = [ - [0.17103, 0.1004, 0.29978], - [0.17087, 0.10414, 0.30337], - [0.17068, 0.10786, 0.30699], - [0.17046, 0.11159, 0.31061], - [0.17023, 0.11524, 0.31422], - [0.16997, 0.11894, 0.31784], - [0.1697, 0.12254, 0.32146], - [0.1694, 0.12624, 0.32509], - [0.16908, 0.12989, 0.32874], - [0.16874, 0.1335, 0.33238], - [0.16837, 0.13713, 0.33601], - [0.16801, 0.14077, 0.33967], - [0.16765, 0.14438, 0.34332], - [0.16728, 0.14799, 0.34698], - [0.16689, 0.1516, 0.35064], - [0.16648, 0.15524, 0.35429], - [0.16605, 0.15887, 0.35797], - [0.16562, 0.16251, 0.36164], - [0.1652, 0.16612, 0.36531], - [0.1648, 0.16979, 0.369], - [0.16439, 0.17341, 0.37268], - [0.16397, 0.17708, 0.37639], - [0.16353, 0.18072, 0.38008], - [0.16308, 0.1844, 0.3838], - [0.16264, 0.1881, 0.3875], - [0.1622, 0.19175, 0.39124], - [0.16176, 0.19545, 0.39496], - [0.16131, 0.19914, 0.3987], - [0.16084, 0.20287, 0.40244], - [0.16036, 0.20662, 0.40621], - [0.15991, 0.21033, 0.40998], - [0.15947, 0.21408, 0.41376], - [0.15904, 0.21784, 0.41755], - [0.1586, 0.2216, 0.42135], - [0.15814, 0.22538, 0.42518], - [0.15768, 0.22918, 0.42901], - [0.15723, 0.23298, 0.43287], - [0.15681, 0.23683, 0.43674], - [0.15639, 0.24063, 0.44063], - [0.15595, 0.24449, 0.44456], - [0.15552, 0.24839, 0.44851], - [0.1551, 0.25226, 0.45249], - [0.15469, 0.25615, 0.45649], - [0.15431, 0.26008, 0.46054], - [0.15394, 0.26403, 0.46464], - [0.1536, 0.26797, 0.46878], - [0.15329, 0.27194, 0.47296], - [0.153, 0.27597, 0.47721], - [0.15276, 0.27998, 0.48152], - [0.15256, 0.28401, 0.48589], - [0.15241, 0.28806, 0.49034], - [0.15232, 0.29214, 0.49486], - [0.1523, 0.29622, 0.49944], - [0.15234, 0.30031, 0.50414], - [0.15246, 0.30441, 0.5089], - [0.15267, 0.30853, 0.51375], - [0.15298, 0.31262, 0.51869], - [0.15339, 0.31673, 0.52371], - [0.15391, 0.32082, 0.52882], - [0.15456, 0.32486, 0.53399], - [0.15532, 0.32892, 0.53926], - [0.15623, 0.33293, 0.5446], - [0.15721, 0.33688, 0.55], - [0.15838, 0.3408, 0.55545], - [0.15962, 0.34465, 0.56096], - [0.16105, 0.34846, 0.56651], - [0.16259, 0.3522, 0.57209], - [0.16426, 0.35588, 0.57769], - [0.166, 0.35947, 0.58331], - [0.1679, 0.36299, 0.58894], - [0.16993, 0.36646, 0.59458], - [0.17202, 0.36982, 0.60021], - [0.17425, 0.37313, 0.60583], - [0.17653, 0.37638, 0.61145], - [0.17895, 0.37954, 0.61705], - [0.1814, 0.38265, 0.62262], - [0.18398, 0.3857, 0.62819], - [0.18662, 0.38871, 0.63374], - [0.18934, 0.39167, 0.63926], - [0.19213, 0.39459, 0.64477], - [0.19503, 0.39748, 0.65028], - [0.19798, 0.40036, 0.65577], - [0.20103, 0.40321, 0.66124], - [0.20423, 0.40606, 0.66671], - [0.20748, 0.40891, 0.67218], - [0.21086, 0.41176, 0.67765], - [0.21438, 0.41463, 0.68311], - [0.21803, 0.41753, 0.68857], - [0.22183, 0.42044, 0.69402], - [0.22582, 0.42338, 0.69948], - [0.22993, 0.42637, 0.70494], - [0.23429, 0.42941, 0.71039], - [0.23881, 0.43249, 0.71584], - [0.24355, 0.43562, 0.72126], - [0.24855, 0.43878, 0.72667], - [0.25373, 0.44203, 0.73207], - [0.25915, 0.4453, 0.73742], - [0.26478, 0.44865, 0.74275], - [0.27068, 0.45204, 0.74803], - [0.27677, 0.45548, 0.75325], - [0.28309, 0.45897, 0.75842], - [0.28962, 0.4625, 0.76352], - [0.29635, 0.46607, 0.76854], - [0.30326, 0.46969, 0.77347], - [0.31037, 0.47331, 0.77832], - [0.3176, 0.47697, 0.78307], - [0.32497, 0.48065, 0.78772], - [0.33249, 0.48433, 0.79227], - [0.34009, 0.48804, 0.7967], - [0.34779, 0.49174, 0.80103], - [0.35555, 0.49542, 0.80525], - [0.36336, 0.49911, 0.80936], - [0.37122, 0.50278, 0.81336], - [0.37911, 0.50644, 0.81727], - [0.38701, 0.51008, 0.82107], - [0.39494, 0.51371, 0.82478], - [0.40285, 0.51731, 0.8284], - [0.41076, 0.52088, 0.83194], - [0.41863, 0.52444, 0.8354], - [0.4265, 0.52797, 0.83878], - [0.43435, 0.53148, 0.84211], - [0.44217, 0.53496, 0.84536], - [0.44995, 0.53844, 0.84856], - [0.45769, 0.54187, 0.85171], - [0.46541, 0.54531, 0.85481], - [0.47308, 0.54872, 0.85786], - [0.48073, 0.55212, 0.86088], - [0.48834, 0.55549, 0.86386], - [0.49589, 0.55887, 0.8668], - [0.50341, 0.56225, 0.8697], - [0.51089, 0.5656, 0.87258], - [0.51834, 0.56896, 0.87542], - [0.52572, 0.57232, 0.87823], - [0.53305, 0.57568, 0.88101], - [0.54033, 0.57904, 0.88375], - [0.54755, 0.58241, 0.88646], - [0.55471, 0.58579, 0.88913], - [0.5618, 0.58917, 0.89176], - [0.56881, 0.59258, 0.89435], - [0.57576, 0.59599, 0.89689], - [0.5826, 0.59942, 0.89939], - [0.58935, 0.60286, 0.90183], - [0.59601, 0.60632, 0.90422], - [0.60256, 0.6098, 0.90655], - [0.60899, 0.61329, 0.90881], - [0.61529, 0.6168, 0.91102], - [0.62146, 0.62032, 0.91315], - [0.62749, 0.62385, 0.91521], - [0.63338, 0.62739, 0.9172], - [0.63911, 0.63094, 0.9191], - [0.64469, 0.63449, 0.92093], - [0.65011, 0.63804, 0.92269], - [0.65537, 0.64159, 0.92436], - [0.66048, 0.64514, 0.92595], - [0.66542, 0.6487, 0.92746], - [0.67022, 0.65223, 0.9289], - [0.67484, 0.65577, 0.93027], - [0.67933, 0.65928, 0.93157], - [0.68368, 0.66279, 0.93279], - [0.68789, 0.66628, 0.93396], - [0.69197, 0.66977, 0.93506], - [0.69594, 0.67324, 0.93611], - [0.69978, 0.67669, 0.93711], - [0.70354, 0.68012, 0.93806], - [0.7072, 0.68355, 0.93896], - [0.71077, 0.68697, 0.93983], - [0.71427, 0.69038, 0.94067], - [0.71771, 0.69377, 0.94147], - [0.72108, 0.69716, 0.94225], - [0.72441, 0.70054, 0.943], - [0.72769, 0.70392, 0.94373], - [0.73094, 0.70728, 0.94445], - [0.73416, 0.71065, 0.94515], - [0.73734, 0.71401, 0.94583], - [0.74051, 0.71738, 0.94651], - [0.74366, 0.72073, 0.94718], - [0.7468, 0.72408, 0.94784], - [0.74992, 0.72744, 0.9485], - [0.75303, 0.7308, 0.94915], - [0.75615, 0.73416, 0.9498], - [0.75925, 0.73752, 0.95045], - [0.76236, 0.74089, 0.9511], - [0.76546, 0.74426, 0.95174], - [0.76856, 0.74763, 0.95238], - [0.77167, 0.75101, 0.95302], - [0.77477, 0.75438, 0.95367], - [0.77788, 0.75776, 0.95431], - [0.78098, 0.76114, 0.95495], - [0.7841, 0.76453, 0.95559], - [0.78721, 0.76791, 0.95623], - [0.79032, 0.77131, 0.95687], - [0.79344, 0.7747, 0.95752], - [0.79656, 0.77811, 0.95816], - [0.79969, 0.78151, 0.95881], - [0.80281, 0.78492, 0.95945], - [0.80595, 0.78833, 0.9601], - [0.80909, 0.79175, 0.96074], - [0.81222, 0.79517, 0.96139], - [0.81537, 0.79859, 0.96203], - [0.81851, 0.80202, 0.96269], - [0.82167, 0.80545, 0.96334], - [0.82482, 0.80889, 0.96398], - [0.82797, 0.81233, 0.96463], - [0.83114, 0.81577, 0.96529], - [0.8343, 0.81921, 0.96594], - [0.83747, 0.82267, 0.96659], - [0.84064, 0.82612, 0.96725], - [0.84381, 0.82958, 0.9679], - [0.84699, 0.83304, 0.96856], - [0.85017, 0.83651, 0.96921], - [0.85336, 0.83998, 0.96987], - [0.85655, 0.84345, 0.97053], - [0.85974, 0.84693, 0.97118], - [0.86294, 0.85041, 0.97184], - [0.86614, 0.85389, 0.97251], - [0.86934, 0.85739, 0.97316], - [0.87255, 0.86088, 0.97382], - [0.87576, 0.86438, 0.97448], - [0.87897, 0.86788, 0.97515], - [0.88219, 0.87138, 0.97581], - [0.88541, 0.87489, 0.97647], - [0.88864, 0.8784, 0.97714], - [0.89186, 0.88192, 0.9778], - [0.8951, 0.88544, 0.97847], - [0.89833, 0.88896, 0.97914], - [0.90157, 0.89249, 0.97981], - [0.90481, 0.89602, 0.98047], - [0.90806, 0.89956, 0.98114], - [0.9113, 0.9031, 0.98181], - [0.91456, 0.90664, 0.98248], - [0.91781, 0.91019, 0.98315], - [0.92107, 0.91374, 0.98382], - [0.92433, 0.91729, 0.9845], - [0.92759, 0.92084, 0.98517], - [0.93087, 0.92441, 0.98584], - [0.93413, 0.92797, 0.98652], - [0.93741, 0.93154, 0.98719], - [0.94069, 0.93511, 0.98786], - [0.94397, 0.93869, 0.98854], - [0.94725, 0.94227, 0.98921], - [0.95053, 0.94585, 0.98989], - [0.95382, 0.94944, 0.99056], - [0.95711, 0.95303, 0.99124], - [0.9604, 0.95662, 0.99191], - [0.96369, 0.96022, 0.99259], - [0.96698, 0.96382, 0.99326], - [0.97027, 0.96742, 0.99393], - [0.97357, 0.97102, 0.9946], - [0.97686, 0.97463, 0.99527], - [0.98016, 0.97824, 0.99594], - [0.98345, 0.98186, 0.99662], - [0.98675, 0.98548, 0.99728], - [0.99004, 0.9891, 0.99795], - [0.99334, 0.99272, 0.99862], - [0.99662, 0.99634, 0.99929], - [0.99992, 0.99997, 0.99995], -]; - -export const colormap_grayc_data: Array<[number, number, number]> = [ - [1, 1, 1], - [0.99554, 0.99554, 0.99554], - [0.99109, 0.99109, 0.99109], - [0.98664, 0.98664, 0.98664], - [0.9822, 0.9822, 0.9822], - [0.97775, 0.97775, 0.97775], - [0.97332, 0.97332, 0.97332], - [0.96888, 0.96888, 0.96888], - [0.96445, 0.96445, 0.96445], - [0.96003, 0.96003, 0.96003], - [0.95561, 0.95561, 0.95561], - [0.95119, 0.95119, 0.95119], - [0.94678, 0.94678, 0.94678], - [0.94237, 0.94237, 0.94237], - [0.93796, 0.93796, 0.93796], - [0.93355, 0.93355, 0.93355], - [0.92916, 0.92916, 0.92916], - [0.92476, 0.92476, 0.92476], - [0.92037, 0.92037, 0.92037], - [0.91598, 0.91598, 0.91598], - [0.9116, 0.9116, 0.9116], - [0.90723, 0.90723, 0.90723], - [0.90285, 0.90285, 0.90285], - [0.89848, 0.89848, 0.89848], - [0.89411, 0.89411, 0.89411], - [0.88975, 0.88975, 0.88975], - [0.88539, 0.88539, 0.88539], - [0.88103, 0.88103, 0.88103], - [0.87668, 0.87668, 0.87668], - [0.87234, 0.87234, 0.87234], - [0.868, 0.868, 0.868], - [0.86366, 0.86366, 0.86366], - [0.85932, 0.85932, 0.85932], - [0.85499, 0.85499, 0.85499], - [0.85066, 0.85066, 0.85066], - [0.84634, 0.84634, 0.84634], - [0.84203, 0.84203, 0.84203], - [0.83771, 0.83771, 0.83771], - [0.8334, 0.8334, 0.8334], - [0.8291, 0.8291, 0.8291], - [0.82479, 0.82479, 0.82479], - [0.82049, 0.82049, 0.82049], - [0.81621, 0.81621, 0.81621], - [0.81192, 0.81192, 0.81192], - [0.80763, 0.80763, 0.80763], - [0.80335, 0.80335, 0.80335], - [0.79908, 0.79908, 0.79908], - [0.7948, 0.7948, 0.7948], - [0.79053, 0.79053, 0.79053], - [0.78628, 0.78628, 0.78628], - [0.78202, 0.78202, 0.78202], - [0.77776, 0.77776, 0.77776], - [0.77351, 0.77351, 0.77351], - [0.76926, 0.76926, 0.76926], - [0.76503, 0.76503, 0.76503], - [0.76079, 0.76079, 0.76079], - [0.75655, 0.75655, 0.75655], - [0.75232, 0.75232, 0.75232], - [0.7481, 0.7481, 0.7481], - [0.74388, 0.74388, 0.74388], - [0.73967, 0.73967, 0.73967], - [0.73546, 0.73546, 0.73546], - [0.73125, 0.73125, 0.73125], - [0.72705, 0.72705, 0.72705], - [0.72285, 0.72285, 0.72285], - [0.71866, 0.71866, 0.71866], - [0.71447, 0.71447, 0.71447], - [0.71029, 0.71029, 0.71029], - [0.70611, 0.70611, 0.70611], - [0.70193, 0.70193, 0.70193], - [0.69776, 0.69776, 0.69776], - [0.6936, 0.6936, 0.6936], - [0.68945, 0.68945, 0.68945], - [0.68529, 0.68529, 0.68529], - [0.68113, 0.68113, 0.68113], - [0.67699, 0.67699, 0.67699], - [0.67285, 0.67285, 0.67285], - [0.66871, 0.66871, 0.66871], - [0.66457, 0.66457, 0.66457], - [0.66045, 0.66045, 0.66045], - [0.65633, 0.65633, 0.65633], - [0.65221, 0.65221, 0.65221], - [0.64809, 0.64809, 0.64809], - [0.64398, 0.64398, 0.64398], - [0.63989, 0.63989, 0.63989], - [0.63579, 0.63579, 0.63579], - [0.63169, 0.63169, 0.63169], - [0.6276, 0.6276, 0.6276], - [0.62352, 0.62352, 0.62352], - [0.61945, 0.61945, 0.61945], - [0.61536, 0.61536, 0.61536], - [0.6113, 0.6113, 0.6113], - [0.60724, 0.60724, 0.60724], - [0.60317, 0.60317, 0.60317], - [0.59912, 0.59912, 0.59912], - [0.59507, 0.59507, 0.59507], - [0.59102, 0.59102, 0.59102], - [0.58698, 0.58698, 0.58698], - [0.58295, 0.58295, 0.58295], - [0.57892, 0.57892, 0.57892], - [0.57489, 0.57489, 0.57489], - [0.57088, 0.57088, 0.57088], - [0.56687, 0.56687, 0.56687], - [0.56286, 0.56286, 0.56286], - [0.55885, 0.55885, 0.55885], - [0.55486, 0.55486, 0.55486], - [0.55087, 0.55087, 0.55087], - [0.54688, 0.54688, 0.54688], - [0.5429, 0.5429, 0.5429], - [0.53892, 0.53892, 0.53892], - [0.53495, 0.53495, 0.53495], - [0.53098, 0.53098, 0.53098], - [0.52703, 0.52703, 0.52703], - [0.52307, 0.52307, 0.52307], - [0.51912, 0.51912, 0.51912], - [0.51517, 0.51517, 0.51517], - [0.51123, 0.51123, 0.51123], - [0.5073, 0.5073, 0.5073], - [0.50336, 0.50336, 0.50336], - [0.49944, 0.49944, 0.49944], - [0.49553, 0.49553, 0.49553], - [0.49162, 0.49162, 0.49162], - [0.48772, 0.48772, 0.48772], - [0.4838, 0.4838, 0.4838], - [0.47992, 0.47992, 0.47992], - [0.47603, 0.47603, 0.47603], - [0.47215, 0.47215, 0.47215], - [0.46826, 0.46826, 0.46826], - [0.4644, 0.4644, 0.4644], - [0.46052, 0.46052, 0.46052], - [0.45666, 0.45666, 0.45666], - [0.45282, 0.45282, 0.45282], - [0.44897, 0.44897, 0.44897], - [0.44512, 0.44512, 0.44512], - [0.44128, 0.44128, 0.44128], - [0.43746, 0.43746, 0.43746], - [0.43362, 0.43362, 0.43362], - [0.42981, 0.42981, 0.42981], - [0.42599, 0.42599, 0.42599], - [0.42218, 0.42218, 0.42218], - [0.41838, 0.41838, 0.41838], - [0.41459, 0.41459, 0.41459], - [0.41081, 0.41081, 0.41081], - [0.40702, 0.40702, 0.40702], - [0.40324, 0.40324, 0.40324], - [0.39946, 0.39946, 0.39946], - [0.39571, 0.39571, 0.39571], - [0.39195, 0.39195, 0.39195], - [0.3882, 0.3882, 0.3882], - [0.38445, 0.38445, 0.38445], - [0.38072, 0.38072, 0.38072], - [0.37699, 0.37699, 0.37699], - [0.37325, 0.37325, 0.37325], - [0.36953, 0.36953, 0.36953], - [0.36583, 0.36583, 0.36583], - [0.36212, 0.36212, 0.36212], - [0.35841, 0.35841, 0.35841], - [0.35474, 0.35474, 0.35474], - [0.35105, 0.35105, 0.35105], - [0.34737, 0.34737, 0.34737], - [0.34368, 0.34368, 0.34368], - [0.34003, 0.34003, 0.34003], - [0.33635, 0.33635, 0.33635], - [0.33272, 0.33272, 0.33272], - [0.32907, 0.32907, 0.32907], - [0.32541, 0.32541, 0.32541], - [0.32179, 0.32179, 0.32179], - [0.31817, 0.31817, 0.31817], - [0.31454, 0.31454, 0.31454], - [0.31095, 0.31095, 0.31095], - [0.30732, 0.30732, 0.30732], - [0.30373, 0.30373, 0.30373], - [0.30014, 0.30014, 0.30014], - [0.29657, 0.29657, 0.29657], - [0.29298, 0.29298, 0.29298], - [0.28943, 0.28943, 0.28943], - [0.28585, 0.28585, 0.28585], - [0.28232, 0.28232, 0.28232], - [0.27877, 0.27877, 0.27877], - [0.27523, 0.27523, 0.27523], - [0.27168, 0.27168, 0.27168], - [0.26816, 0.26816, 0.26816], - [0.26465, 0.26465, 0.26465], - [0.26115, 0.26115, 0.26115], - [0.25764, 0.25764, 0.25764], - [0.25417, 0.25417, 0.25417], - [0.25067, 0.25067, 0.25067], - [0.2472, 0.2472, 0.2472], - [0.24372, 0.24372, 0.24372], - [0.24026, 0.24026, 0.24026], - [0.23684, 0.23684, 0.23684], - [0.23336, 0.23336, 0.23336], - [0.22992, 0.22992, 0.22992], - [0.22652, 0.22652, 0.22652], - [0.22311, 0.22311, 0.22311], - [0.21969, 0.21969, 0.21969], - [0.2163, 0.2163, 0.2163], - [0.21288, 0.21288, 0.21288], - [0.2095, 0.2095, 0.2095], - [0.20615, 0.20615, 0.20615], - [0.20275, 0.20275, 0.20275], - [0.19938, 0.19938, 0.19938], - [0.19606, 0.19606, 0.19606], - [0.19271, 0.19271, 0.19271], - [0.18938, 0.18938, 0.18938], - [0.18607, 0.18607, 0.18607], - [0.18272, 0.18272, 0.18272], - [0.17943, 0.17943, 0.17943], - [0.17611, 0.17611, 0.17611], - [0.17284, 0.17284, 0.17284], - [0.1696, 0.1696, 0.1696], - [0.16631, 0.16631, 0.16631], - [0.16307, 0.16307, 0.16307], - [0.15978, 0.15978, 0.15978], - [0.15658, 0.15658, 0.15658], - [0.15332, 0.15332, 0.15332], - [0.15014, 0.15014, 0.15014], - [0.1469, 0.1469, 0.1469], - [0.14372, 0.14372, 0.14372], - [0.14054, 0.14054, 0.14054], - [0.13737, 0.13737, 0.13737], - [0.1342, 0.1342, 0.1342], - [0.13105, 0.13105, 0.13105], - [0.12789, 0.12789, 0.12789], - [0.12473, 0.12473, 0.12473], - [0.12159, 0.12159, 0.12159], - [0.11854, 0.11854, 0.11854], - [0.1154, 0.1154, 0.1154], - [0.11234, 0.11234, 0.11234], - [0.10927, 0.10927, 0.10927], - [0.1062, 0.1062, 0.1062], - [0.10313, 0.10313, 0.10313], - [0.10006, 0.10006, 0.10006], - [0.097002, 0.097004, 0.097003], - [0.094024, 0.094026, 0.094026], - [0.091021, 0.091024, 0.091023], - [0.087931, 0.087933, 0.087932], - [0.084744, 0.084745, 0.084745], - [0.081468, 0.08147, 0.081469], - [0.077984, 0.077985, 0.077985], - [0.074504, 0.074505, 0.074505], - [0.070845, 0.070846, 0.070846], - [0.067013, 0.067014, 0.067014], - [0.063057, 0.063057, 0.063057], - [0.058816, 0.058816, 0.058816], - [0.054339, 0.054339, 0.054339], - [0.04971, 0.04971, 0.04971], - [0.044716, 0.044716, 0.044716], - [0.03933, 0.039331, 0.03933], - [0.033552, 0.033552, 0.033552], - [0.028009, 0.028009, 0.028009], - [0.022447, 0.022447, 0.022447], - [0.016884, 0.016884, 0.016884], - [0.011219, 0.011219, 0.011219], - [0.0055636, 0.0055636, 0.0055636], - [9.8794e-7, 9.8901e-7, 9.8874e-7], -]; - -export const colormap_hawaii_data: Array<[number, number, number]> = [ - [0.55054, 0.006842, 0.45198], - [0.55149, 0.015367, 0.44797], - [0.55243, 0.023795, 0.444], - [0.55333, 0.032329, 0.44002], - [0.55423, 0.04117, 0.43606], - [0.5551, 0.049286, 0.43213], - [0.55595, 0.056667, 0.42819], - [0.5568, 0.063525, 0.42427], - [0.55762, 0.06997, 0.42038], - [0.55841, 0.076028, 0.41651], - [0.55921, 0.081936, 0.41266], - [0.55999, 0.087507, 0.40882], - [0.56075, 0.092811, 0.40501], - [0.56149, 0.098081, 0.40124], - [0.56224, 0.10313, 0.39747], - [0.56295, 0.108, 0.39374], - [0.56366, 0.11287, 0.39002], - [0.56435, 0.11753, 0.38634], - [0.56503, 0.12212, 0.3827], - [0.56571, 0.12668, 0.37907], - [0.56638, 0.13117, 0.37547], - [0.56704, 0.13554, 0.3719], - [0.56768, 0.13987, 0.36838], - [0.56831, 0.1442, 0.36486], - [0.56894, 0.14842, 0.36138], - [0.56956, 0.15262, 0.35794], - [0.57017, 0.15681, 0.35452], - [0.57078, 0.16093, 0.35113], - [0.57138, 0.16501, 0.34776], - [0.57197, 0.16912, 0.34442], - [0.57256, 0.17313, 0.34112], - [0.57314, 0.17717, 0.33784], - [0.57371, 0.18114, 0.3346], - [0.57428, 0.18515, 0.33136], - [0.57484, 0.18909, 0.32817], - [0.57541, 0.19304, 0.32499], - [0.57597, 0.19698, 0.32185], - [0.57652, 0.20085, 0.31874], - [0.57706, 0.20478, 0.31565], - [0.5776, 0.20866, 0.31256], - [0.57814, 0.21254, 0.30954], - [0.57868, 0.21643, 0.30652], - [0.57921, 0.22029, 0.3035], - [0.57975, 0.22411, 0.30052], - [0.58027, 0.22798, 0.29757], - [0.58079, 0.23182, 0.29462], - [0.58131, 0.23565, 0.29171], - [0.58183, 0.23946, 0.28881], - [0.58235, 0.24327, 0.28591], - [0.58287, 0.2471, 0.28307], - [0.58339, 0.25092, 0.2802], - [0.5839, 0.25474, 0.27738], - [0.58442, 0.25853, 0.27455], - [0.58493, 0.26234, 0.27174], - [0.58544, 0.26616, 0.26898], - [0.58595, 0.26997, 0.2662], - [0.58646, 0.27377, 0.26344], - [0.58696, 0.27758, 0.26068], - [0.58747, 0.28137, 0.25793], - [0.58797, 0.28518, 0.25522], - [0.58848, 0.28901, 0.25249], - [0.58898, 0.29282, 0.24977], - [0.58949, 0.29665, 0.24708], - [0.59, 0.30047, 0.24438], - [0.59051, 0.3043, 0.24172], - [0.59102, 0.30814, 0.23903], - [0.59153, 0.31197, 0.23638], - [0.59204, 0.31585, 0.23369], - [0.59255, 0.3197, 0.23106], - [0.59305, 0.32356, 0.22842], - [0.59356, 0.32743, 0.22577], - [0.59407, 0.33131, 0.22313], - [0.59458, 0.33523, 0.22051], - [0.5951, 0.33913, 0.21787], - [0.59561, 0.34305, 0.21523], - [0.59613, 0.34698, 0.21261], - [0.59664, 0.35092, 0.20999], - [0.59716, 0.35488, 0.20739], - [0.59768, 0.35883, 0.20478], - [0.5982, 0.36282, 0.20215], - [0.59872, 0.36683, 0.19953], - [0.59925, 0.37084, 0.19696], - [0.59977, 0.37488, 0.19437], - [0.60029, 0.37893, 0.19174], - [0.60082, 0.38301, 0.18915], - [0.60135, 0.38709, 0.18655], - [0.60187, 0.39122, 0.18395], - [0.6024, 0.39535, 0.18134], - [0.60293, 0.39949, 0.17878], - [0.60346, 0.40368, 0.17616], - [0.604, 0.40787, 0.17359], - [0.60452, 0.4121, 0.17101], - [0.60504, 0.41635, 0.16844], - [0.60556, 0.42062, 0.16585], - [0.60608, 0.42493, 0.16332], - [0.60661, 0.42925, 0.16073], - [0.60713, 0.4336, 0.1582], - [0.60764, 0.438, 0.15565], - [0.60814, 0.44241, 0.15309], - [0.60864, 0.44685, 0.15058], - [0.60913, 0.45132, 0.14807], - [0.60961, 0.45583, 0.14561], - [0.61008, 0.46036, 0.14312], - [0.61054, 0.46493, 0.14069], - [0.61099, 0.46954, 0.13827], - [0.61142, 0.47417, 0.13583], - [0.61183, 0.47884, 0.13351], - [0.61223, 0.48354, 0.13121], - [0.6126, 0.48829, 0.12892], - [0.61295, 0.49305, 0.12672], - [0.61327, 0.49788, 0.12457], - [0.61357, 0.5027, 0.12249], - [0.61384, 0.50759, 0.12051], - [0.61407, 0.5125, 0.11867], - [0.61426, 0.51746, 0.11685], - [0.61442, 0.52243, 0.11516], - [0.61453, 0.52746, 0.11366], - [0.61459, 0.53251, 0.11227], - [0.61461, 0.53759, 0.11103], - [0.61457, 0.54271, 0.11], - [0.61447, 0.54785, 0.10911], - [0.61431, 0.55302, 0.10842], - [0.61408, 0.55821, 0.10801], - [0.61379, 0.56345, 0.10785], - [0.61342, 0.56868, 0.10794], - [0.61297, 0.57395, 0.10831], - [0.61245, 0.57923, 0.10903], - [0.61184, 0.58452, 0.11004], - [0.61115, 0.58982, 0.11132], - [0.61035, 0.59513, 0.11296], - [0.60947, 0.60044, 0.11486], - [0.60849, 0.60575, 0.11717], - [0.60741, 0.61106, 0.11981], - [0.60622, 0.61635, 0.12276], - [0.60493, 0.62162, 0.12612], - [0.60354, 0.62688, 0.12976], - [0.60203, 0.63211, 0.13369], - [0.60041, 0.63731, 0.13797], - [0.59869, 0.64247, 0.1425], - [0.59686, 0.64759, 0.14733], - [0.59492, 0.65266, 0.15242], - [0.59287, 0.6577, 0.15779], - [0.59071, 0.66267, 0.16342], - [0.58844, 0.66758, 0.16926], - [0.58608, 0.67243, 0.17528], - [0.58361, 0.67721, 0.18151], - [0.58105, 0.68192, 0.18799], - [0.57839, 0.68656, 0.19459], - [0.57565, 0.69112, 0.20131], - [0.57281, 0.69561, 0.20824], - [0.56988, 0.70002, 0.21528], - [0.56689, 0.70435, 0.22247], - [0.56381, 0.7086, 0.22974], - [0.56066, 0.71275, 0.23717], - [0.55746, 0.71684, 0.24462], - [0.55418, 0.72084, 0.25222], - [0.55085, 0.72477, 0.25987], - [0.54747, 0.7286, 0.26757], - [0.54404, 0.73238, 0.27539], - [0.54057, 0.73606, 0.28324], - [0.53707, 0.73968, 0.29114], - [0.53351, 0.74323, 0.29909], - [0.52994, 0.7467, 0.30708], - [0.52633, 0.75011, 0.31511], - [0.5227, 0.75346, 0.32319], - [0.51905, 0.75675, 0.33128], - [0.51537, 0.75998, 0.33944], - [0.51168, 0.76316, 0.3476], - [0.50799, 0.76629, 0.35578], - [0.50428, 0.76937, 0.36398], - [0.50055, 0.77241, 0.37222], - [0.49682, 0.77541, 0.38048], - [0.49309, 0.77836, 0.38876], - [0.48935, 0.78129, 0.39705], - [0.48561, 0.78418, 0.40538], - [0.48188, 0.78704, 0.41371], - [0.47814, 0.78987, 0.42206], - [0.47441, 0.79267, 0.43044], - [0.47068, 0.79546, 0.43882], - [0.46695, 0.79822, 0.44724], - [0.46322, 0.80096, 0.45567], - [0.45952, 0.80369, 0.46412], - [0.45581, 0.80641, 0.47258], - [0.45212, 0.80911, 0.48105], - [0.44844, 0.8118, 0.48955], - [0.44477, 0.81447, 0.49809], - [0.44111, 0.81714, 0.50662], - [0.43749, 0.8198, 0.51517], - [0.43386, 0.82246, 0.52375], - [0.43028, 0.82511, 0.53235], - [0.42672, 0.82776, 0.54096], - [0.42319, 0.8304, 0.5496], - [0.41971, 0.83304, 0.55824], - [0.41626, 0.83567, 0.56692], - [0.41287, 0.83831, 0.57561], - [0.40952, 0.84094, 0.58431], - [0.40624, 0.84356, 0.59304], - [0.40304, 0.84619, 0.60178], - [0.3999, 0.84882, 0.61054], - [0.39687, 0.85144, 0.61932], - [0.39395, 0.85406, 0.6281], - [0.39115, 0.85668, 0.63691], - [0.38847, 0.8593, 0.64571], - [0.38593, 0.86192, 0.65453], - [0.38359, 0.86453, 0.66337], - [0.38141, 0.86713, 0.6722], - [0.37942, 0.86973, 0.68102], - [0.37767, 0.87232, 0.68986], - [0.37617, 0.87491, 0.69869], - [0.37492, 0.87748, 0.70751], - [0.37398, 0.88005, 0.71632], - [0.37334, 0.8826, 0.72511], - [0.37304, 0.88514, 0.73387], - [0.37311, 0.88765, 0.7426], - [0.37357, 0.89016, 0.7513], - [0.37444, 0.89264, 0.75995], - [0.37572, 0.8951, 0.76855], - [0.37747, 0.89752, 0.7771], - [0.37967, 0.89992, 0.78557], - [0.38235, 0.90229, 0.79397], - [0.38553, 0.90462, 0.80228], - [0.38921, 0.90691, 0.8105], - [0.39338, 0.90916, 0.81862], - [0.39807, 0.91137, 0.82663], - [0.40326, 0.91353, 0.83451], - [0.40893, 0.91563, 0.84226], - [0.41508, 0.91769, 0.84986], - [0.4217, 0.91968, 0.85731], - [0.42879, 0.92161, 0.86461], - [0.43631, 0.92349, 0.87173], - [0.44423, 0.92529, 0.87868], - [0.45254, 0.92703, 0.88545], - [0.4612, 0.9287, 0.89204], - [0.47021, 0.93031, 0.89842], - [0.47952, 0.93184, 0.90462], - [0.4891, 0.9333, 0.91062], - [0.49895, 0.93469, 0.91641], - [0.50902, 0.936, 0.92201], - [0.51928, 0.93725, 0.92739], - [0.52972, 0.93842, 0.93259], - [0.54029, 0.93952, 0.93759], - [0.551, 0.94055, 0.9424], - [0.5618, 0.94151, 0.94702], - [0.57269, 0.94241, 0.95146], - [0.58362, 0.94324, 0.95573], - [0.59461, 0.94402, 0.95982], - [0.60561, 0.94473, 0.96377], - [0.61664, 0.94539, 0.96756], - [0.62765, 0.94599, 0.97121], - [0.63865, 0.94654, 0.97474], - [0.64962, 0.94705, 0.97815], - [0.66055, 0.94751, 0.98145], - [0.67144, 0.94793, 0.98465], - [0.68228, 0.94832, 0.98777], - [0.69306, 0.94866, 0.9908], - [0.70378, 0.94898, 0.99377], -]; - -export const colormap_imola_data: Array<[number, number, number]> = [ - [0.10144, 0.20011, 0.70019], - [0.10328, 0.20301, 0.69881], - [0.10496, 0.2059, 0.69742], - [0.10673, 0.20873, 0.69605], - [0.1083, 0.21157, 0.69466], - [0.10998, 0.21437, 0.69329], - [0.11152, 0.21716, 0.69191], - [0.11307, 0.21994, 0.69053], - [0.1145, 0.2227, 0.68917], - [0.11603, 0.22544, 0.6878], - [0.11744, 0.22819, 0.68643], - [0.11891, 0.23089, 0.68508], - [0.12028, 0.23359, 0.68371], - [0.12166, 0.23631, 0.68236], - [0.12304, 0.23898, 0.68101], - [0.12442, 0.24167, 0.67966], - [0.12581, 0.24432, 0.67832], - [0.12711, 0.247, 0.67698], - [0.12847, 0.24964, 0.67564], - [0.12983, 0.2523, 0.67431], - [0.13114, 0.25495, 0.67298], - [0.13245, 0.25757, 0.67165], - [0.13376, 0.2602, 0.67033], - [0.13507, 0.26282, 0.669], - [0.13633, 0.26543, 0.66768], - [0.13768, 0.26803, 0.66636], - [0.13894, 0.27067, 0.66505], - [0.14023, 0.27326, 0.66374], - [0.14154, 0.27587, 0.66243], - [0.14282, 0.27845, 0.66112], - [0.14411, 0.28103, 0.65982], - [0.14542, 0.28363, 0.65851], - [0.14665, 0.2862, 0.65721], - [0.14795, 0.2888, 0.65591], - [0.14923, 0.29139, 0.65461], - [0.1505, 0.29395, 0.65331], - [0.15176, 0.29654, 0.65202], - [0.15303, 0.29912, 0.65072], - [0.15432, 0.30167, 0.64943], - [0.15561, 0.30425, 0.64813], - [0.15688, 0.30683, 0.64684], - [0.15816, 0.30941, 0.64554], - [0.15942, 0.31195, 0.64425], - [0.16069, 0.31453, 0.64296], - [0.162, 0.31711, 0.64166], - [0.16327, 0.31968, 0.64038], - [0.16454, 0.32224, 0.63908], - [0.16579, 0.3248, 0.63778], - [0.16711, 0.32737, 0.63649], - [0.16838, 0.32995, 0.63519], - [0.16969, 0.33252, 0.63389], - [0.17096, 0.33508, 0.63258], - [0.17225, 0.33763, 0.63128], - [0.17355, 0.3402, 0.62996], - [0.17488, 0.34276, 0.62865], - [0.17615, 0.34531, 0.62732], - [0.17752, 0.34788, 0.62599], - [0.17884, 0.35043, 0.62466], - [0.18016, 0.35298, 0.62331], - [0.1815, 0.35554, 0.62195], - [0.18287, 0.35807, 0.62059], - [0.18426, 0.3606, 0.61922], - [0.18569, 0.36314, 0.61782], - [0.18708, 0.36567, 0.61641], - [0.18851, 0.36819, 0.61498], - [0.18994, 0.37069, 0.61354], - [0.19141, 0.3732, 0.61208], - [0.19291, 0.37569, 0.61061], - [0.19445, 0.37818, 0.60911], - [0.19597, 0.38066, 0.60758], - [0.19753, 0.38312, 0.60602], - [0.1991, 0.38556, 0.60446], - [0.20072, 0.388, 0.60285], - [0.20237, 0.39043, 0.60122], - [0.20408, 0.39284, 0.59957], - [0.20577, 0.39524, 0.59788], - [0.2075, 0.39762, 0.59617], - [0.20925, 0.39999, 0.59443], - [0.21105, 0.40234, 0.59266], - [0.21285, 0.40469, 0.59085], - [0.2147, 0.40702, 0.58902], - [0.21659, 0.40934, 0.58717], - [0.21847, 0.41164, 0.5853], - [0.22041, 0.41394, 0.58339], - [0.22233, 0.41622, 0.58145], - [0.22427, 0.41849, 0.57951], - [0.22629, 0.42075, 0.57752], - [0.2283, 0.423, 0.57553], - [0.23029, 0.42526, 0.57351], - [0.23235, 0.42751, 0.57147], - [0.23442, 0.42974, 0.56941], - [0.23649, 0.43198, 0.56735], - [0.23856, 0.43419, 0.56526], - [0.24066, 0.43643, 0.56318], - [0.24278, 0.43865, 0.56106], - [0.24491, 0.44088, 0.55895], - [0.24707, 0.44313, 0.55684], - [0.24923, 0.44536, 0.55471], - [0.25141, 0.44759, 0.55258], - [0.25359, 0.44985, 0.55045], - [0.25578, 0.45212, 0.54832], - [0.25799, 0.45438, 0.54619], - [0.26024, 0.45666, 0.54406], - [0.26249, 0.45896, 0.54194], - [0.26475, 0.46126, 0.53983], - [0.26703, 0.46359, 0.53775], - [0.26936, 0.46593, 0.53565], - [0.27167, 0.4683, 0.53358], - [0.27404, 0.4707, 0.53154], - [0.27644, 0.47311, 0.52952], - [0.27885, 0.47557, 0.52751], - [0.28127, 0.47804, 0.52553], - [0.28375, 0.48054, 0.52358], - [0.28625, 0.48309, 0.52165], - [0.28882, 0.48567, 0.51977], - [0.29141, 0.48829, 0.51792], - [0.29401, 0.49095, 0.5161], - [0.29669, 0.49364, 0.51433], - [0.2994, 0.49638, 0.51259], - [0.30213, 0.49917, 0.5109], - [0.30494, 0.502, 0.50925], - [0.30776, 0.50487, 0.50764], - [0.31067, 0.5078, 0.50607], - [0.31359, 0.51076, 0.50456], - [0.31656, 0.51377, 0.50307], - [0.31958, 0.51683, 0.50165], - [0.32265, 0.51992, 0.50025], - [0.32573, 0.52308, 0.4989], - [0.3289, 0.52626, 0.4976], - [0.33208, 0.52949, 0.49631], - [0.33532, 0.53276, 0.49508], - [0.33856, 0.53606, 0.49387], - [0.34187, 0.5394, 0.49269], - [0.34521, 0.54278, 0.49157], - [0.34858, 0.54619, 0.49045], - [0.35197, 0.54963, 0.48934], - [0.35542, 0.55309, 0.48829], - [0.35885, 0.5566, 0.48724], - [0.36235, 0.56012, 0.4862], - [0.36585, 0.56367, 0.48519], - [0.36938, 0.56724, 0.48419], - [0.37293, 0.57082, 0.4832], - [0.37652, 0.57443, 0.48223], - [0.3801, 0.57806, 0.48125], - [0.38371, 0.58171, 0.4803], - [0.38733, 0.58538, 0.47934], - [0.39098, 0.58905, 0.47839], - [0.39463, 0.59275, 0.47744], - [0.39831, 0.59645, 0.4765], - [0.40198, 0.60017, 0.47556], - [0.40569, 0.60391, 0.47462], - [0.4094, 0.60765, 0.47366], - [0.41313, 0.6114, 0.47272], - [0.41686, 0.61516, 0.47179], - [0.4206, 0.61895, 0.47084], - [0.42436, 0.62273, 0.4699], - [0.42813, 0.62653, 0.46895], - [0.43192, 0.63035, 0.468], - [0.43571, 0.63417, 0.46706], - [0.43951, 0.638, 0.46609], - [0.44332, 0.64184, 0.46514], - [0.44714, 0.64569, 0.4642], - [0.45098, 0.64956, 0.46322], - [0.45484, 0.65343, 0.46226], - [0.45869, 0.65732, 0.46131], - [0.46255, 0.66121, 0.46033], - [0.46643, 0.66511, 0.45937], - [0.47033, 0.66903, 0.4584], - [0.47423, 0.67296, 0.45742], - [0.47814, 0.67689, 0.45645], - [0.48206, 0.68083, 0.45547], - [0.48599, 0.68479, 0.4545], - [0.48994, 0.68877, 0.4535], - [0.4939, 0.69275, 0.45253], - [0.49787, 0.69673, 0.45153], - [0.50185, 0.70073, 0.45054], - [0.50583, 0.70474, 0.44955], - [0.50983, 0.70877, 0.44855], - [0.51385, 0.71279, 0.44754], - [0.51788, 0.71685, 0.44654], - [0.5219, 0.72089, 0.44553], - [0.52596, 0.72497, 0.44454], - [0.53002, 0.72904, 0.44352], - [0.53409, 0.73313, 0.44251], - [0.53819, 0.73723, 0.44149], - [0.54228, 0.74134, 0.44047], - [0.5464, 0.74546, 0.43945], - [0.55052, 0.74959, 0.43843], - [0.55466, 0.75374, 0.43741], - [0.55881, 0.7579, 0.43638], - [0.563, 0.76207, 0.43535], - [0.5672, 0.76625, 0.43431], - [0.57141, 0.77044, 0.43327], - [0.57565, 0.77464, 0.43225], - [0.57992, 0.77886, 0.43121], - [0.5842, 0.78309, 0.43016], - [0.58853, 0.78733, 0.42912], - [0.5929, 0.79158, 0.42808], - [0.5973, 0.79584, 0.42705], - [0.60174, 0.80012, 0.426], - [0.60624, 0.8044, 0.42497], - [0.6108, 0.80869, 0.42393], - [0.61541, 0.81299, 0.42289], - [0.62011, 0.81731, 0.42187], - [0.62487, 0.82163, 0.42085], - [0.62973, 0.82595, 0.41984], - [0.63468, 0.83028, 0.41883], - [0.63974, 0.83461, 0.41784], - [0.6449, 0.83894, 0.41687], - [0.65019, 0.84326, 0.41589], - [0.6556, 0.84759, 0.41494], - [0.66115, 0.8519, 0.41401], - [0.66684, 0.8562, 0.4131], - [0.67269, 0.86048, 0.41221], - [0.67868, 0.86474, 0.41134], - [0.68483, 0.86898, 0.41052], - [0.69114, 0.87318, 0.4097], - [0.69761, 0.87735, 0.40892], - [0.70424, 0.88148, 0.40818], - [0.71102, 0.88557, 0.40747], - [0.71795, 0.8896, 0.4068], - [0.72504, 0.89358, 0.40617], - [0.73226, 0.89751, 0.40557], - [0.73962, 0.90138, 0.40501], - [0.74709, 0.90518, 0.40448], - [0.75469, 0.90892, 0.40401], - [0.76238, 0.9126, 0.40357], - [0.77017, 0.9162, 0.40317], - [0.77806, 0.91975, 0.4028], - [0.78601, 0.92323, 0.40246], - [0.79403, 0.92664, 0.40216], - [0.80211, 0.92999, 0.40189], - [0.81023, 0.93328, 0.40166], - [0.8184, 0.93653, 0.40145], - [0.8266, 0.93971, 0.40127], - [0.83482, 0.94285, 0.40112], - [0.84307, 0.94593, 0.40098], - [0.85132, 0.94898, 0.40086], - [0.8596, 0.95199, 0.40075], - [0.86788, 0.95497, 0.40067], - [0.87616, 0.95791, 0.40059], - [0.88445, 0.96083, 0.40052], - [0.89274, 0.96371, 0.40047], - [0.90102, 0.96658, 0.40042], - [0.9093, 0.96943, 0.40038], - [0.91758, 0.97226, 0.40034], - [0.92584, 0.97507, 0.40031], - [0.93411, 0.97788, 0.40028], - [0.94237, 0.98067, 0.40026], - [0.95062, 0.98345, 0.40023], - [0.95887, 0.98623, 0.40021], - [0.96711, 0.98899, 0.40019], - [0.97534, 0.99175, 0.40017], - [0.98357, 0.9945, 0.40014], - [0.9918, 0.99724, 0.40012], - [1, 0.99999, 0.40009], -]; - -export const colormap_lajolla_data: Array<[number, number, number]> = [ - [0.99983, 0.99974, 0.79991], - [0.99953, 0.99725, 0.79292], - [0.99921, 0.99476, 0.78593], - [0.99887, 0.99226, 0.77894], - [0.99851, 0.98977, 0.77195], - [0.99814, 0.98727, 0.76497], - [0.99775, 0.98476, 0.75798], - [0.99735, 0.98225, 0.75099], - [0.99693, 0.97973, 0.74399], - [0.9965, 0.97721, 0.73699], - [0.99606, 0.97467, 0.73], - [0.9956, 0.97213, 0.72299], - [0.99512, 0.96958, 0.71599], - [0.99464, 0.96701, 0.70898], - [0.99414, 0.96443, 0.70195], - [0.99363, 0.96183, 0.69492], - [0.9931, 0.95921, 0.68789], - [0.99256, 0.95657, 0.68085], - [0.99201, 0.95391, 0.6738], - [0.99145, 0.95123, 0.66674], - [0.99087, 0.94851, 0.65967], - [0.99028, 0.94576, 0.65258], - [0.98967, 0.94298, 0.64549], - [0.98905, 0.94017, 0.63838], - [0.98842, 0.93731, 0.63126], - [0.98777, 0.9344, 0.62413], - [0.98711, 0.93145, 0.61698], - [0.98643, 0.92845, 0.60981], - [0.98573, 0.92539, 0.60264], - [0.98502, 0.92228, 0.59545], - [0.9843, 0.91909, 0.58824], - [0.98354, 0.91584, 0.58103], - [0.98278, 0.91253, 0.57381], - [0.982, 0.90913, 0.56658], - [0.98119, 0.90566, 0.55934], - [0.98036, 0.90211, 0.55211], - [0.97951, 0.89846, 0.54486], - [0.97864, 0.89474, 0.53764], - [0.97775, 0.89091, 0.53041], - [0.97683, 0.887, 0.52321], - [0.97589, 0.88298, 0.51602], - [0.97493, 0.87887, 0.50888], - [0.97394, 0.87466, 0.50176], - [0.97294, 0.87036, 0.4947], - [0.9719, 0.86595, 0.48769], - [0.97084, 0.86145, 0.48073], - [0.96976, 0.85685, 0.47387], - [0.96866, 0.85217, 0.4671], - [0.96754, 0.84738, 0.4604], - [0.96639, 0.84253, 0.45384], - [0.96523, 0.83758, 0.44738], - [0.96405, 0.83256, 0.44107], - [0.96286, 0.82747, 0.4349], - [0.96165, 0.82232, 0.42887], - [0.96044, 0.81711, 0.42301], - [0.95921, 0.81186, 0.41734], - [0.95797, 0.80656, 0.41183], - [0.95673, 0.80123, 0.40651], - [0.95548, 0.79587, 0.40139], - [0.95423, 0.79049, 0.39647], - [0.95298, 0.7851, 0.39176], - [0.95173, 0.7797, 0.38724], - [0.95049, 0.7743, 0.38296], - [0.94925, 0.76891, 0.37886], - [0.94802, 0.76354, 0.37498], - [0.9468, 0.75818, 0.37129], - [0.94558, 0.75284, 0.36782], - [0.94438, 0.74753, 0.36455], - [0.94319, 0.74225, 0.36147], - [0.942, 0.73699, 0.35857], - [0.94083, 0.73178, 0.35587], - [0.93968, 0.72659, 0.35332], - [0.93853, 0.72144, 0.35096], - [0.9374, 0.71634, 0.34874], - [0.93628, 0.71126, 0.34667], - [0.93517, 0.70623, 0.34475], - [0.93407, 0.70122, 0.34297], - [0.93299, 0.69626, 0.3413], - [0.93191, 0.69133, 0.33977], - [0.93086, 0.68644, 0.33832], - [0.9298, 0.68157, 0.33699], - [0.92876, 0.67675, 0.33575], - [0.92773, 0.67194, 0.33461], - [0.9267, 0.66716, 0.33354], - [0.92569, 0.66242, 0.33255], - [0.92468, 0.65769, 0.3316], - [0.92368, 0.65297, 0.33073], - [0.92268, 0.64829, 0.32993], - [0.92169, 0.64362, 0.32917], - [0.92069, 0.63897, 0.32845], - [0.91971, 0.63434, 0.32777], - [0.91872, 0.6297, 0.32713], - [0.91775, 0.62509, 0.32653], - [0.91676, 0.62049, 0.32595], - [0.91577, 0.61589, 0.32541], - [0.9148, 0.61131, 0.32489], - [0.91381, 0.60672, 0.32439], - [0.91282, 0.60214, 0.32391], - [0.91183, 0.59757, 0.32345], - [0.91084, 0.59299, 0.32301], - [0.90983, 0.58841, 0.32257], - [0.90882, 0.58384, 0.32214], - [0.90781, 0.57926, 0.32172], - [0.90677, 0.57467, 0.32131], - [0.90574, 0.57009, 0.32091], - [0.90468, 0.5655, 0.32052], - [0.90361, 0.5609, 0.32013], - [0.90252, 0.5563, 0.31973], - [0.90141, 0.55169, 0.31934], - [0.90028, 0.54706, 0.31895], - [0.89913, 0.54243, 0.31856], - [0.89794, 0.53779, 0.31817], - [0.89674, 0.53312, 0.31778], - [0.89549, 0.52845, 0.31739], - [0.89421, 0.52375, 0.31699], - [0.89288, 0.51905, 0.3166], - [0.89151, 0.51432, 0.3162], - [0.89009, 0.50957, 0.31579], - [0.88862, 0.50481, 0.31537], - [0.88709, 0.50001, 0.31494], - [0.88549, 0.4952, 0.31451], - [0.88383, 0.49037, 0.31408], - [0.88209, 0.4855, 0.31363], - [0.88027, 0.48062, 0.31317], - [0.87836, 0.47572, 0.31269], - [0.87636, 0.47078, 0.31219], - [0.87426, 0.46581, 0.3117], - [0.87206, 0.46083, 0.3112], - [0.86973, 0.45582, 0.31068], - [0.86729, 0.45079, 0.31013], - [0.86473, 0.44572, 0.30956], - [0.86203, 0.44064, 0.30897], - [0.85918, 0.43556, 0.30835], - [0.8562, 0.43044, 0.3077], - [0.85306, 0.42531, 0.30705], - [0.84977, 0.42017, 0.30638], - [0.8463, 0.41502, 0.30567], - [0.84268, 0.40989, 0.30492], - [0.83888, 0.40473, 0.30415], - [0.83492, 0.3996, 0.30334], - [0.83077, 0.3945, 0.30251], - [0.82645, 0.38942, 0.30164], - [0.82195, 0.38436, 0.30075], - [0.81728, 0.37934, 0.29982], - [0.81242, 0.37438, 0.29885], - [0.80741, 0.36945, 0.29783], - [0.80221, 0.36459, 0.2968], - [0.79686, 0.35981, 0.2957], - [0.79135, 0.35512, 0.29457], - [0.78568, 0.35049, 0.29341], - [0.77987, 0.34593, 0.29222], - [0.77392, 0.34151, 0.29098], - [0.76784, 0.33718, 0.28969], - [0.76164, 0.33295, 0.28837], - [0.75533, 0.32883, 0.28699], - [0.74891, 0.32481, 0.28559], - [0.7424, 0.32094, 0.28415], - [0.7358, 0.31716, 0.28268], - [0.72913, 0.31351, 0.28113], - [0.72238, 0.30998, 0.27958], - [0.71559, 0.30656, 0.27796], - [0.70873, 0.30323, 0.27631], - [0.70182, 0.30005, 0.2746], - [0.69488, 0.29697, 0.27286], - [0.68791, 0.29396, 0.27108], - [0.68091, 0.29108, 0.26927], - [0.67389, 0.28828, 0.26736], - [0.66685, 0.28556, 0.26546], - [0.6598, 0.28295, 0.26352], - [0.65273, 0.28037, 0.26149], - [0.64566, 0.27791, 0.25945], - [0.63859, 0.2755, 0.25734], - [0.63151, 0.27312, 0.25521], - [0.62444, 0.27082, 0.253], - [0.61736, 0.26855, 0.25076], - [0.61029, 0.26633, 0.24848], - [0.60322, 0.26415, 0.24612], - [0.59616, 0.26199, 0.24373], - [0.58909, 0.25987, 0.24132], - [0.58204, 0.25775, 0.23883], - [0.575, 0.25567, 0.23633], - [0.56797, 0.2536, 0.23373], - [0.56093, 0.25155, 0.23114], - [0.55391, 0.24948, 0.22849], - [0.5469, 0.24745, 0.22578], - [0.53989, 0.2454, 0.22304], - [0.53291, 0.24336, 0.22025], - [0.52592, 0.24134, 0.21742], - [0.51895, 0.2393, 0.21455], - [0.51198, 0.23728, 0.21167], - [0.50503, 0.23523, 0.20871], - [0.49809, 0.23315, 0.20576], - [0.49117, 0.23112, 0.20274], - [0.48423, 0.22906, 0.1997], - [0.47733, 0.227, 0.19669], - [0.47045, 0.2249, 0.1936], - [0.46356, 0.22286, 0.19048], - [0.4567, 0.22079, 0.18738], - [0.44986, 0.21868, 0.18422], - [0.44303, 0.2166, 0.18105], - [0.43621, 0.21449, 0.17792], - [0.42941, 0.2124, 0.17473], - [0.42262, 0.21028, 0.17151], - [0.41587, 0.20818, 0.16831], - [0.40912, 0.20608, 0.16509], - [0.40239, 0.20397, 0.16193], - [0.39569, 0.20182, 0.15872], - [0.389, 0.1997, 0.1555], - [0.38233, 0.1976, 0.15228], - [0.37568, 0.19547, 0.1491], - [0.36906, 0.19337, 0.14593], - [0.36245, 0.19124, 0.14274], - [0.35588, 0.18913, 0.13954], - [0.34931, 0.18702, 0.13639], - [0.34278, 0.18492, 0.13329], - [0.33625, 0.18278, 0.13021], - [0.32977, 0.18068, 0.12705], - [0.32329, 0.17861, 0.12397], - [0.31684, 0.17648, 0.12091], - [0.31043, 0.17441, 0.11793], - [0.30401, 0.17231, 0.11488], - [0.29764, 0.17023, 0.11196], - [0.2913, 0.16814, 0.109], - [0.28496, 0.16607, 0.1061], - [0.27867, 0.16404, 0.10321], - [0.27237, 0.16197, 0.10032], - [0.26614, 0.15986, 0.09752], - [0.25991, 0.15783, 0.094764], - [0.25371, 0.1558, 0.092001], - [0.24753, 0.15373, 0.08926], - [0.24138, 0.1517, 0.086567], - [0.23526, 0.1497, 0.083951], - [0.22914, 0.14766, 0.081329], - [0.22307, 0.14566, 0.078687], - [0.21702, 0.14362, 0.07612], - [0.211, 0.14161, 0.073581], - [0.20503, 0.13954, 0.070837], - [0.19909, 0.13759, 0.068084], - [0.19322, 0.13553, 0.065213], - [0.1874, 0.13354, 0.062323], - [0.18156, 0.13153, 0.059337], - [0.1758, 0.12951, 0.056198], - [0.17011, 0.12748, 0.052899], - [0.16445, 0.12548, 0.04964], - [0.15883, 0.12342, 0.046062], - [0.15323, 0.12139, 0.042482], - [0.14773, 0.1194, 0.038691], - [0.14225, 0.11735, 0.03474], - [0.13682, 0.11532, 0.030784], - [0.13146, 0.11332, 0.026943], - [0.12616, 0.11125, 0.02311], - [0.12086, 0.1092, 0.019283], - [0.1157, 0.10713, 0.01546], - [0.11058, 0.10499, 0.011622], - [0.10549, 0.10296, 0.0076238], - [0.10023, 0.10091, 0.0037913], -]; - -export const colormap_lapaz_data: Array<[number, number, number]> = [ - [0.10352, 0.047787, 0.39353], - [0.10489, 0.053521, 0.39674], - [0.10638, 0.059148, 0.39996], - [0.10772, 0.064483, 0.40319], - [0.1091, 0.06976, 0.4064], - [0.11045, 0.074827, 0.40961], - [0.11175, 0.079829, 0.41283], - [0.11305, 0.084796, 0.41603], - [0.11424, 0.089643, 0.41924], - [0.11551, 0.094446, 0.42243], - [0.11673, 0.099126, 0.42564], - [0.11793, 0.10381, 0.42883], - [0.11911, 0.10838, 0.43203], - [0.12024, 0.11303, 0.4352], - [0.12136, 0.11751, 0.43837], - [0.12248, 0.12198, 0.44154], - [0.12359, 0.12648, 0.4447], - [0.1247, 0.13094, 0.44784], - [0.12581, 0.13532, 0.45099], - [0.12683, 0.13967, 0.45412], - [0.12791, 0.14407, 0.45724], - [0.12892, 0.14838, 0.46034], - [0.12999, 0.1527, 0.46344], - [0.13099, 0.15701, 0.46653], - [0.13199, 0.16132, 0.46961], - [0.13298, 0.16553, 0.47266], - [0.13398, 0.16983, 0.47572], - [0.13497, 0.17405, 0.47874], - [0.13589, 0.17829, 0.48176], - [0.13689, 0.18246, 0.48476], - [0.13789, 0.18667, 0.48776], - [0.13882, 0.19085, 0.49073], - [0.13975, 0.19504, 0.49367], - [0.14077, 0.19918, 0.4966], - [0.14171, 0.20336, 0.49951], - [0.14266, 0.20751, 0.50242], - [0.14363, 0.21165, 0.50529], - [0.14459, 0.21578, 0.50816], - [0.14558, 0.21989, 0.51099], - [0.1465, 0.22398, 0.51382], - [0.14749, 0.22811, 0.51661], - [0.14844, 0.2322, 0.51939], - [0.14946, 0.23628, 0.52213], - [0.15044, 0.24033, 0.52487], - [0.15142, 0.2444, 0.52758], - [0.15243, 0.24849, 0.53026], - [0.15344, 0.25253, 0.53293], - [0.15448, 0.25657, 0.53556], - [0.15554, 0.26061, 0.53818], - [0.1566, 0.26464, 0.54076], - [0.15765, 0.26868, 0.54333], - [0.15876, 0.27268, 0.54587], - [0.15981, 0.2767, 0.54838], - [0.16096, 0.28068, 0.55086], - [0.16211, 0.28467, 0.55332], - [0.16326, 0.28867, 0.55574], - [0.16443, 0.29264, 0.55815], - [0.16559, 0.29662, 0.56053], - [0.16684, 0.30057, 0.56289], - [0.16805, 0.30453, 0.56519], - [0.16935, 0.30849, 0.5675], - [0.17061, 0.31241, 0.56975], - [0.17192, 0.31636, 0.57199], - [0.17326, 0.32029, 0.57419], - [0.17465, 0.32419, 0.57638], - [0.17601, 0.3281, 0.57851], - [0.17748, 0.33201, 0.58063], - [0.17892, 0.3359, 0.5827], - [0.18039, 0.33979, 0.58476], - [0.18191, 0.34365, 0.58678], - [0.18348, 0.34753, 0.58876], - [0.18509, 0.35138, 0.59073], - [0.1867, 0.35524, 0.59266], - [0.18839, 0.35907, 0.59455], - [0.19007, 0.3629, 0.59641], - [0.19181, 0.36673, 0.59824], - [0.19361, 0.37054, 0.60004], - [0.19542, 0.37436, 0.6018], - [0.1973, 0.37814, 0.60353], - [0.19919, 0.38193, 0.60522], - [0.20114, 0.3857, 0.60689], - [0.20317, 0.38948, 0.60852], - [0.20521, 0.39324, 0.6101], - [0.20732, 0.39698, 0.61166], - [0.20945, 0.40074, 0.61318], - [0.21167, 0.40445, 0.61467], - [0.2139, 0.40817, 0.61612], - [0.21621, 0.41188, 0.61754], - [0.21855, 0.41558, 0.61892], - [0.22096, 0.41927, 0.62026], - [0.22341, 0.42293, 0.62156], - [0.22593, 0.4266, 0.62283], - [0.2285, 0.43025, 0.62407], - [0.23111, 0.43388, 0.62525], - [0.23377, 0.43753, 0.62641], - [0.23654, 0.44113, 0.62752], - [0.23932, 0.44474, 0.6286], - [0.24218, 0.44832, 0.62963], - [0.24508, 0.4519, 0.63064], - [0.24809, 0.45546, 0.63159], - [0.25112, 0.459, 0.6325], - [0.25422, 0.46252, 0.63338], - [0.25738, 0.46604, 0.63421], - [0.2606, 0.46955, 0.635], - [0.2639, 0.47302, 0.63575], - [0.26722, 0.47649, 0.63646], - [0.27066, 0.47994, 0.63712], - [0.27412, 0.48336, 0.63774], - [0.27766, 0.48677, 0.63831], - [0.28125, 0.49016, 0.63885], - [0.28491, 0.49353, 0.63933], - [0.28864, 0.49688, 0.63978], - [0.29243, 0.5002, 0.64018], - [0.29628, 0.50351, 0.64052], - [0.30018, 0.50679, 0.64083], - [0.30415, 0.51005, 0.64108], - [0.30818, 0.51329, 0.6413], - [0.31225, 0.51649, 0.64146], - [0.31642, 0.51968, 0.64158], - [0.32063, 0.52284, 0.64165], - [0.32486, 0.52597, 0.64168], - [0.3292, 0.52907, 0.64166], - [0.33356, 0.53214, 0.64158], - [0.33797, 0.53517, 0.64147], - [0.34246, 0.53819, 0.6413], - [0.34698, 0.54115, 0.64109], - [0.35154, 0.5441, 0.64083], - [0.35617, 0.54701, 0.64052], - [0.36082, 0.54989, 0.64017], - [0.36554, 0.55273, 0.63977], - [0.37029, 0.55553, 0.63932], - [0.37509, 0.5583, 0.63882], - [0.37993, 0.56104, 0.63828], - [0.3848, 0.56374, 0.6377], - [0.38971, 0.56639, 0.63707], - [0.39466, 0.569, 0.6364], - [0.39963, 0.57158, 0.63567], - [0.40464, 0.57411, 0.63491], - [0.4097, 0.57662, 0.63412], - [0.41476, 0.57907, 0.63327], - [0.41986, 0.58148, 0.63238], - [0.42498, 0.58386, 0.63146], - [0.43012, 0.58619, 0.63051], - [0.43529, 0.58847, 0.6295], - [0.44047, 0.59072, 0.62848], - [0.44567, 0.59294, 0.62741], - [0.4509, 0.5951, 0.62631], - [0.45613, 0.59723, 0.62518], - [0.46139, 0.59931, 0.62402], - [0.46666, 0.60135, 0.62283], - [0.47194, 0.60335, 0.62161], - [0.47722, 0.60531, 0.62039], - [0.48252, 0.60725, 0.61913], - [0.48784, 0.60914, 0.61784], - [0.49315, 0.61099, 0.61655], - [0.49849, 0.61279, 0.61523], - [0.50382, 0.61458, 0.6139], - [0.50917, 0.61633, 0.61257], - [0.51452, 0.61805, 0.61123], - [0.51987, 0.61974, 0.60988], - [0.52524, 0.6214, 0.60853], - [0.53062, 0.62303, 0.60718], - [0.536, 0.62464, 0.60582], - [0.54139, 0.62623, 0.60448], - [0.54681, 0.6278, 0.60314], - [0.55222, 0.62935, 0.60182], - [0.55765, 0.63089, 0.60051], - [0.56309, 0.63241, 0.59923], - [0.56854, 0.63393, 0.59796], - [0.57402, 0.63543, 0.59673], - [0.57952, 0.63694, 0.59553], - [0.58503, 0.63844, 0.59436], - [0.59056, 0.63995, 0.59324], - [0.59612, 0.64146, 0.59217], - [0.6017, 0.64299, 0.59114], - [0.60733, 0.64453, 0.59016], - [0.61297, 0.64609, 0.58925], - [0.61866, 0.64767, 0.58841], - [0.62438, 0.64929, 0.58765], - [0.63014, 0.65093, 0.58696], - [0.63594, 0.6526, 0.58636], - [0.64179, 0.65432, 0.58586], - [0.64769, 0.6561, 0.58545], - [0.65365, 0.65791, 0.58514], - [0.65966, 0.65978, 0.58495], - [0.66573, 0.66172, 0.58488], - [0.67185, 0.66373, 0.58495], - [0.67805, 0.6658, 0.58515], - [0.6843, 0.66795, 0.58549], - [0.69062, 0.67019, 0.58599], - [0.69702, 0.67251, 0.58664], - [0.70348, 0.67492, 0.58747], - [0.71002, 0.67743, 0.58847], - [0.71662, 0.68003, 0.58967], - [0.72329, 0.68276, 0.59106], - [0.73003, 0.68559, 0.59265], - [0.73684, 0.68853, 0.59444], - [0.74371, 0.69159, 0.59646], - [0.75064, 0.69476, 0.59869], - [0.75762, 0.69806, 0.60115], - [0.76465, 0.70148, 0.60385], - [0.77173, 0.70503, 0.60677], - [0.77884, 0.70871, 0.60994], - [0.78598, 0.71249, 0.61334], - [0.79313, 0.71641, 0.617], - [0.80029, 0.72043, 0.62089], - [0.80745, 0.72458, 0.62501], - [0.81459, 0.72884, 0.62938], - [0.82171, 0.73321, 0.63398], - [0.82878, 0.73767, 0.6388], - [0.8358, 0.74224, 0.64385], - [0.84275, 0.74689, 0.64912], - [0.84963, 0.75162, 0.65458], - [0.8564, 0.75642, 0.66025], - [0.86308, 0.76129, 0.6661], - [0.86964, 0.76622, 0.67213], - [0.87606, 0.7712, 0.67832], - [0.88235, 0.77622, 0.68466], - [0.88848, 0.78127, 0.69113], - [0.89445, 0.78634, 0.69774], - [0.90025, 0.79142, 0.70446], - [0.90588, 0.79651, 0.71129], - [0.91132, 0.80161, 0.7182], - [0.91657, 0.8067, 0.72519], - [0.92163, 0.81176, 0.73224], - [0.92649, 0.81681, 0.73935], - [0.93115, 0.82184, 0.7465], - [0.93562, 0.82683, 0.75368], - [0.93989, 0.83179, 0.7609], - [0.94396, 0.83671, 0.76812], - [0.94784, 0.84159, 0.77536], - [0.95153, 0.84642, 0.78261], - [0.95503, 0.8512, 0.78985], - [0.95835, 0.85595, 0.79708], - [0.96148, 0.86064, 0.80431], - [0.96444, 0.86528, 0.81152], - [0.96724, 0.86987, 0.8187], - [0.96988, 0.87442, 0.82587], - [0.97236, 0.87892, 0.83302], - [0.97468, 0.88337, 0.84014], - [0.97687, 0.88777, 0.84724], - [0.97893, 0.89214, 0.85431], - [0.98085, 0.89646, 0.86136], - [0.98265, 0.90074, 0.86839], - [0.98434, 0.90498, 0.87538], - [0.98591, 0.90918, 0.88236], - [0.98739, 0.91335, 0.88932], - [0.98876, 0.9175, 0.89625], - [0.99005, 0.92161, 0.90317], - [0.99126, 0.92569, 0.91007], - [0.99239, 0.92975, 0.91695], - [0.99344, 0.93379, 0.92382], - [0.99443, 0.93782, 0.93068], - [0.99536, 0.94182, 0.93753], - [0.99624, 0.94581, 0.94437], - [0.99706, 0.94979, 0.95121], -]; - -export const colormap_lisbon_data: Array<[number, number, number]> = [ - [0.90019, 0.89986, 0.99991], - [0.88957, 0.8921, 0.9936], - [0.87895, 0.88435, 0.9873], - [0.86836, 0.8766, 0.981], - [0.85776, 0.86888, 0.97471], - [0.84718, 0.86115, 0.96843], - [0.83662, 0.85344, 0.96215], - [0.82607, 0.84574, 0.95589], - [0.81553, 0.83806, 0.94962], - [0.80499, 0.83038, 0.94336], - [0.79448, 0.82271, 0.93711], - [0.78398, 0.81505, 0.93086], - [0.77348, 0.8074, 0.92462], - [0.763, 0.79976, 0.91838], - [0.75253, 0.79212, 0.91216], - [0.74208, 0.7845, 0.90593], - [0.73164, 0.77688, 0.89972], - [0.72122, 0.76927, 0.8935], - [0.71081, 0.76167, 0.8873], - [0.70041, 0.75408, 0.8811], - [0.69002, 0.74649, 0.87491], - [0.67965, 0.73892, 0.86872], - [0.6693, 0.73134, 0.86254], - [0.65896, 0.72378, 0.85636], - [0.64863, 0.71623, 0.85019], - [0.63832, 0.70868, 0.84402], - [0.62803, 0.70113, 0.83787], - [0.61774, 0.6936, 0.83171], - [0.60748, 0.68607, 0.82555], - [0.59723, 0.67854, 0.8194], - [0.58699, 0.67103, 0.81326], - [0.57678, 0.66352, 0.80713], - [0.56658, 0.65601, 0.80098], - [0.55639, 0.6485, 0.79485], - [0.54623, 0.641, 0.78872], - [0.53607, 0.63351, 0.78258], - [0.52594, 0.62601, 0.77644], - [0.51581, 0.61852, 0.7703], - [0.50571, 0.61104, 0.76416], - [0.49564, 0.60355, 0.75801], - [0.48558, 0.59606, 0.75185], - [0.47555, 0.58857, 0.74568], - [0.46551, 0.58109, 0.73951], - [0.45552, 0.57361, 0.73331], - [0.44554, 0.56612, 0.7271], - [0.4356, 0.55862, 0.72086], - [0.42566, 0.55113, 0.71459], - [0.41576, 0.54363, 0.70831], - [0.40589, 0.53612, 0.70197], - [0.39604, 0.52861, 0.69561], - [0.38621, 0.52108, 0.6892], - [0.37644, 0.51355, 0.68272], - [0.3667, 0.506, 0.6762], - [0.357, 0.49846, 0.66961], - [0.34734, 0.4909, 0.66295], - [0.33772, 0.48331, 0.65622], - [0.32816, 0.47573, 0.6494], - [0.31867, 0.46812, 0.64248], - [0.30926, 0.46051, 0.63547], - [0.29989, 0.45291, 0.62837], - [0.29062, 0.44528, 0.62115], - [0.28145, 0.43766, 0.61382], - [0.27237, 0.43002, 0.60638], - [0.26344, 0.42238, 0.59882], - [0.25462, 0.41477, 0.59114], - [0.2459, 0.40715, 0.58333], - [0.23739, 0.39954, 0.57541], - [0.22901, 0.39196, 0.56736], - [0.22082, 0.3844, 0.55919], - [0.21278, 0.37688, 0.55092], - [0.20499, 0.36938, 0.54253], - [0.1974, 0.36193, 0.53402], - [0.19002, 0.35453, 0.52543], - [0.18288, 0.34718, 0.51674], - [0.17599, 0.33988, 0.50798], - [0.1694, 0.33265, 0.49912], - [0.16302, 0.32546, 0.49021], - [0.15689, 0.31838, 0.48124], - [0.15103, 0.31136, 0.47222], - [0.14549, 0.30442, 0.46315], - [0.14012, 0.29756, 0.45407], - [0.13509, 0.29078, 0.44496], - [0.1303, 0.28408, 0.43583], - [0.12572, 0.27748, 0.42669], - [0.12135, 0.27096, 0.41756], - [0.11727, 0.2645, 0.40842], - [0.11345, 0.25812, 0.3993], - [0.10981, 0.25186, 0.39021], - [0.10635, 0.24564, 0.38115], - [0.10306, 0.23952, 0.37208], - [0.099941, 0.23345, 0.36307], - [0.097002, 0.2275, 0.35409], - [0.094303, 0.22159, 0.34515], - [0.091713, 0.21576, 0.33624], - [0.08922, 0.20999, 0.32738], - [0.086919, 0.20432, 0.31857], - [0.084717, 0.19867, 0.30982], - [0.082644, 0.19313, 0.30108], - [0.080696, 0.18768, 0.29243], - [0.078849, 0.18223, 0.28382], - [0.077157, 0.17692, 0.27529], - [0.075616, 0.17166, 0.26679], - [0.074219, 0.16651, 0.25838], - [0.072907, 0.16146, 0.25002], - [0.071722, 0.15647, 0.24178], - [0.070637, 0.15156, 0.23358], - [0.069756, 0.14679, 0.22551], - [0.068993, 0.14217, 0.21752], - [0.068301, 0.13767, 0.20963], - [0.067772, 0.13328, 0.20186], - [0.067395, 0.12903, 0.19427], - [0.067165, 0.12499, 0.18675], - [0.067086, 0.1211, 0.17943], - [0.06716, 0.11745, 0.17227], - [0.06739, 0.114, 0.1653], - [0.067779, 0.11082, 0.1586], - [0.068337, 0.10781, 0.15205], - [0.069084, 0.1051, 0.14582], - [0.069909, 0.10272, 0.13976], - [0.070958, 0.10059, 0.13409], - [0.07215, 0.098812, 0.12866], - [0.073639, 0.097347, 0.12356], - [0.075176, 0.096199, 0.11887], - [0.076956, 0.095493, 0.11442], - [0.078977, 0.095119, 0.11047], - [0.081272, 0.095095, 0.10685], - [0.08373, 0.095427, 0.10358], - [0.086376, 0.0961, 0.10069], - [0.089318, 0.097212, 0.098263], - [0.092445, 0.098697, 0.096142], - [0.095823, 0.1005, 0.094539], - [0.099434, 0.1027, 0.093176], - [0.10331, 0.10518, 0.092312], - [0.10736, 0.10803, 0.091807], - [0.11165, 0.11122, 0.091623], - [0.11615, 0.11461, 0.091779], - [0.12079, 0.11839, 0.092234], - [0.12572, 0.1223, 0.092972], - [0.13079, 0.12655, 0.094115], - [0.13596, 0.13101, 0.09548], - [0.14139, 0.13561, 0.097052], - [0.14689, 0.14047, 0.098938], - [0.15255, 0.1455, 0.10101], - [0.15837, 0.15062, 0.10334], - [0.16427, 0.15594, 0.1058], - [0.17026, 0.16138, 0.10841], - [0.17633, 0.16692, 0.11128], - [0.18252, 0.17255, 0.11419], - [0.18882, 0.17834, 0.11728], - [0.19515, 0.18416, 0.12049], - [0.20155, 0.19009, 0.12381], - [0.20805, 0.19611, 0.12723], - [0.21458, 0.20216, 0.13079], - [0.22119, 0.20831, 0.13438], - [0.22783, 0.2145, 0.13805], - [0.23454, 0.22078, 0.14177], - [0.24127, 0.22707, 0.14559], - [0.24807, 0.23339, 0.14942], - [0.2549, 0.2398, 0.1533], - [0.26176, 0.24624, 0.15725], - [0.26868, 0.25273, 0.16129], - [0.27563, 0.25926, 0.16528], - [0.28262, 0.26581, 0.16941], - [0.28963, 0.27238, 0.17349], - [0.29669, 0.27902, 0.17766], - [0.30376, 0.28566, 0.18179], - [0.3109, 0.29236, 0.18603], - [0.31804, 0.29909, 0.19023], - [0.32522, 0.30585, 0.19452], - [0.33245, 0.31261, 0.19876], - [0.3397, 0.31943, 0.20308], - [0.34697, 0.32626, 0.20741], - [0.35426, 0.33314, 0.21177], - [0.3616, 0.34004, 0.21615], - [0.36896, 0.34696, 0.22055], - [0.37635, 0.3539, 0.22493], - [0.38376, 0.36087, 0.22938], - [0.3912, 0.36788, 0.23384], - [0.39866, 0.37491, 0.23833], - [0.40617, 0.38197, 0.24285], - [0.41369, 0.38907, 0.24741], - [0.42124, 0.39618, 0.25198], - [0.42882, 0.40333, 0.25657], - [0.43643, 0.41052, 0.26122], - [0.44408, 0.41772, 0.2659], - [0.45174, 0.42496, 0.27062], - [0.45943, 0.43224, 0.27538], - [0.46716, 0.43954, 0.28017], - [0.47492, 0.44688, 0.28502], - [0.48269, 0.45427, 0.28994], - [0.49051, 0.46168, 0.29492], - [0.49836, 0.46915, 0.29998], - [0.50622, 0.47664, 0.3051], - [0.51414, 0.48418, 0.31031], - [0.52207, 0.49178, 0.3156], - [0.53005, 0.4994, 0.32098], - [0.53805, 0.50709, 0.32645], - [0.54608, 0.51482, 0.33206], - [0.55413, 0.52259, 0.33776], - [0.56223, 0.53042, 0.34359], - [0.57033, 0.5383, 0.34955], - [0.57847, 0.54623, 0.35565], - [0.58663, 0.5542, 0.36188], - [0.59481, 0.56223, 0.36826], - [0.60301, 0.57029, 0.37478], - [0.61122, 0.57841, 0.38147], - [0.61944, 0.58657, 0.38831], - [0.62766, 0.59478, 0.39532], - [0.63589, 0.60302, 0.40247], - [0.64412, 0.6113, 0.40981], - [0.65234, 0.61961, 0.41731], - [0.66055, 0.62795, 0.42496], - [0.66876, 0.63632, 0.43277], - [0.67694, 0.6447, 0.44072], - [0.6851, 0.6531, 0.44885], - [0.69323, 0.66153, 0.45711], - [0.70133, 0.66997, 0.46551], - [0.70942, 0.67841, 0.47407], - [0.71746, 0.68685, 0.48274], - [0.72547, 0.6953, 0.49156], - [0.73343, 0.70375, 0.50046], - [0.74136, 0.7122, 0.5095], - [0.74926, 0.72065, 0.51864], - [0.75712, 0.72909, 0.52786], - [0.76495, 0.73752, 0.53719], - [0.77273, 0.74596, 0.5466], - [0.78049, 0.75439, 0.55608], - [0.78821, 0.7628, 0.56564], - [0.7959, 0.77122, 0.57527], - [0.80357, 0.77962, 0.58497], - [0.81121, 0.78803, 0.59472], - [0.81882, 0.79643, 0.60453], - [0.82642, 0.80483, 0.61437], - [0.834, 0.81323, 0.62428], - [0.84156, 0.82163, 0.63423], - [0.84911, 0.83004, 0.64421], - [0.85665, 0.83844, 0.65423], - [0.86419, 0.84685, 0.66429], - [0.87171, 0.85527, 0.67438], - [0.87923, 0.8637, 0.6845], - [0.88675, 0.87213, 0.69466], - [0.89427, 0.88056, 0.70484], - [0.90179, 0.88902, 0.71505], - [0.90931, 0.89748, 0.7253], - [0.91683, 0.90595, 0.73555], - [0.92435, 0.91443, 0.74584], - [0.93188, 0.92293, 0.75615], - [0.93942, 0.93143, 0.76649], - [0.94696, 0.93996, 0.77685], - [0.9545, 0.94849, 0.78723], - [0.96204, 0.95704, 0.79763], - [0.9696, 0.9656, 0.80806], - [0.97716, 0.97418, 0.81851], - [0.98473, 0.98277, 0.82899], - [0.9923, 0.99138, 0.83948], - [0.99987, 1, 0.84999], -]; - -export const colormap_nuuk_data: Array<[number, number, number]> = [ - [0.018013, 0.35076, 0.55062], - [0.025926, 0.35177, 0.54917], - [0.033826, 0.35281, 0.54772], - [0.042005, 0.35384, 0.54628], - [0.049338, 0.35491, 0.54484], - [0.056017, 0.35596, 0.54341], - [0.062265, 0.35703, 0.54199], - [0.068128, 0.3581, 0.54059], - [0.073701, 0.35918, 0.5392], - [0.078892, 0.36028, 0.53783], - [0.084046, 0.36141, 0.53646], - [0.088911, 0.36254, 0.53511], - [0.093625, 0.36368, 0.53377], - [0.098277, 0.36485, 0.53247], - [0.10277, 0.36604, 0.53117], - [0.1072, 0.36724, 0.5299], - [0.11153, 0.36847, 0.52866], - [0.1158, 0.36971, 0.52743], - [0.11998, 0.37098, 0.52624], - [0.12415, 0.37227, 0.52507], - [0.12832, 0.3736, 0.52393], - [0.13244, 0.37494, 0.52282], - [0.1365, 0.37633, 0.52173], - [0.14062, 0.37772, 0.52069], - [0.14469, 0.37915, 0.51968], - [0.14872, 0.38062, 0.51871], - [0.15279, 0.3821, 0.51778], - [0.15688, 0.38364, 0.51688], - [0.16097, 0.38519, 0.51602], - [0.16503, 0.38678, 0.51521], - [0.16919, 0.38842, 0.51445], - [0.17328, 0.39007, 0.51373], - [0.17746, 0.39178, 0.51305], - [0.18159, 0.39352, 0.51242], - [0.18583, 0.3953, 0.51185], - [0.19003, 0.3971, 0.51132], - [0.19431, 0.39896, 0.51085], - [0.19855, 0.40087, 0.51043], - [0.20287, 0.40279, 0.51007], - [0.20723, 0.40475, 0.50977], - [0.21161, 0.40677, 0.50952], - [0.21602, 0.40882, 0.50933], - [0.22047, 0.41091, 0.50919], - [0.22491, 0.41305, 0.50912], - [0.22943, 0.41521, 0.50911], - [0.23398, 0.41742, 0.50915], - [0.23855, 0.41967, 0.50926], - [0.24317, 0.42194, 0.50943], - [0.24784, 0.42427, 0.50965], - [0.25252, 0.42664, 0.50994], - [0.25723, 0.42904, 0.51029], - [0.26198, 0.43148, 0.51071], - [0.26676, 0.43393, 0.51118], - [0.27156, 0.43644, 0.51171], - [0.27643, 0.43897, 0.51231], - [0.28128, 0.44155, 0.51296], - [0.28617, 0.44415, 0.51367], - [0.29112, 0.44677, 0.51444], - [0.29607, 0.44943, 0.51526], - [0.30104, 0.45213, 0.51613], - [0.30607, 0.45484, 0.51707], - [0.31108, 0.45757, 0.51805], - [0.31614, 0.46033, 0.51909], - [0.32119, 0.46311, 0.52016], - [0.32627, 0.46592, 0.52129], - [0.33138, 0.46876, 0.52247], - [0.3365, 0.47162, 0.52369], - [0.34165, 0.47448, 0.52495], - [0.3468, 0.47736, 0.52626], - [0.35195, 0.48027, 0.52759], - [0.35714, 0.48318, 0.52897], - [0.36232, 0.48612, 0.53037], - [0.3675, 0.48906, 0.53182], - [0.3727, 0.49202, 0.53328], - [0.37791, 0.49499, 0.53478], - [0.38313, 0.49798, 0.53631], - [0.38834, 0.50096, 0.53786], - [0.39356, 0.50396, 0.53941], - [0.39878, 0.50695, 0.541], - [0.404, 0.50996, 0.5426], - [0.40922, 0.51298, 0.54421], - [0.41443, 0.51599, 0.54584], - [0.41965, 0.51903, 0.54747], - [0.42486, 0.52205, 0.54911], - [0.43006, 0.52509, 0.55075], - [0.43526, 0.52812, 0.5524], - [0.44043, 0.53115, 0.55404], - [0.4456, 0.53418, 0.55567], - [0.45078, 0.53722, 0.55732], - [0.45593, 0.54025, 0.55894], - [0.46106, 0.54328, 0.56056], - [0.46618, 0.54631, 0.56217], - [0.4713, 0.54933, 0.56376], - [0.47638, 0.55235, 0.56532], - [0.48145, 0.55536, 0.56688], - [0.48649, 0.55837, 0.56841], - [0.49153, 0.56138, 0.56991], - [0.49651, 0.56437, 0.57139], - [0.5015, 0.56736, 0.57285], - [0.50643, 0.57033, 0.57426], - [0.51135, 0.57331, 0.57566], - [0.51623, 0.57628, 0.57702], - [0.52109, 0.57922, 0.57833], - [0.52591, 0.58215, 0.57961], - [0.53069, 0.58508, 0.58085], - [0.53543, 0.58798, 0.58204], - [0.54014, 0.59087, 0.58319], - [0.5448, 0.59375, 0.5843], - [0.54942, 0.59662, 0.58536], - [0.55399, 0.59946, 0.58637], - [0.55851, 0.60229, 0.58732], - [0.563, 0.60509, 0.58822], - [0.56743, 0.60789, 0.58908], - [0.5718, 0.61065, 0.58988], - [0.57613, 0.61339, 0.59062], - [0.58039, 0.61612, 0.59131], - [0.5846, 0.61882, 0.59195], - [0.58874, 0.62149, 0.59252], - [0.59285, 0.62415, 0.59303], - [0.59688, 0.62677, 0.59348], - [0.60085, 0.62936, 0.59388], - [0.60476, 0.63194, 0.59421], - [0.60861, 0.63449, 0.59449], - [0.61239, 0.637, 0.5947], - [0.61611, 0.63949, 0.59486], - [0.61977, 0.64195, 0.59495], - [0.62335, 0.64438, 0.59499], - [0.62687, 0.64679, 0.59496], - [0.63033, 0.64916, 0.59488], - [0.63372, 0.65151, 0.59474], - [0.63704, 0.65382, 0.59454], - [0.6403, 0.65611, 0.59429], - [0.64349, 0.65836, 0.59398], - [0.64662, 0.66058, 0.59361], - [0.64969, 0.66278, 0.5932], - [0.65268, 0.66494, 0.59273], - [0.65562, 0.66708, 0.5922], - [0.6585, 0.66919, 0.59162], - [0.66131, 0.67127, 0.59099], - [0.66407, 0.67332, 0.59031], - [0.66676, 0.67535, 0.58959], - [0.66941, 0.67735, 0.58882], - [0.67199, 0.67932, 0.58801], - [0.67452, 0.68126, 0.58716], - [0.677, 0.68319, 0.58627], - [0.67941, 0.68509, 0.58534], - [0.68178, 0.68696, 0.58436], - [0.68411, 0.68881, 0.58334], - [0.68639, 0.69063, 0.58229], - [0.68862, 0.69245, 0.58121], - [0.6908, 0.69423, 0.5801], - [0.69296, 0.696, 0.57894], - [0.69506, 0.69774, 0.57776], - [0.69712, 0.69947, 0.57656], - [0.69915, 0.70119, 0.57532], - [0.70115, 0.70289, 0.57405], - [0.70311, 0.70457, 0.57277], - [0.70504, 0.70624, 0.57145], - [0.70694, 0.70789, 0.57012], - [0.70881, 0.70953, 0.56877], - [0.71065, 0.71116, 0.5674], - [0.71247, 0.71278, 0.566], - [0.71426, 0.71439, 0.56459], - [0.71604, 0.716, 0.56318], - [0.7178, 0.71759, 0.56174], - [0.71953, 0.71917, 0.56028], - [0.72124, 0.72075, 0.55881], - [0.72295, 0.72233, 0.55735], - [0.72464, 0.7239, 0.55585], - [0.72632, 0.72548, 0.55437], - [0.72799, 0.72705, 0.55288], - [0.72965, 0.72862, 0.55138], - [0.7313, 0.7302, 0.54988], - [0.73296, 0.73177, 0.54838], - [0.73461, 0.73335, 0.54687], - [0.73625, 0.73494, 0.54537], - [0.73789, 0.73652, 0.54387], - [0.73955, 0.73812, 0.54238], - [0.7412, 0.73974, 0.54089], - [0.74286, 0.74135, 0.53941], - [0.74453, 0.743, 0.53795], - [0.74621, 0.74464, 0.5365], - [0.7479, 0.74631, 0.53506], - [0.7496, 0.748, 0.53363], - [0.75133, 0.7497, 0.53225], - [0.75307, 0.75144, 0.53087], - [0.75484, 0.75318, 0.52952], - [0.75662, 0.75497, 0.5282], - [0.75844, 0.75678, 0.52692], - [0.76028, 0.75863, 0.52567], - [0.76216, 0.76051, 0.52445], - [0.76407, 0.76242, 0.52329], - [0.76603, 0.76438, 0.52216], - [0.76802, 0.76638, 0.52109], - [0.77006, 0.76843, 0.52008], - [0.77215, 0.77053, 0.51913], - [0.77428, 0.77269, 0.51825], - [0.77648, 0.77489, 0.51743], - [0.77873, 0.77717, 0.51669], - [0.78104, 0.7795, 0.51602], - [0.78342, 0.7819, 0.51545], - [0.78587, 0.78437, 0.51498], - [0.78839, 0.78691, 0.51461], - [0.79099, 0.78953, 0.51434], - [0.79367, 0.79223, 0.51418], - [0.79642, 0.79501, 0.51415], - [0.79927, 0.79787, 0.51424], - [0.80219, 0.80083, 0.51446], - [0.80521, 0.80388, 0.51482], - [0.80833, 0.80702, 0.51533], - [0.81154, 0.81024, 0.51599], - [0.81483, 0.81357, 0.51683], - [0.81823, 0.81699, 0.51782], - [0.82173, 0.8205, 0.51899], - [0.82531, 0.82411, 0.52032], - [0.829, 0.82782, 0.52184], - [0.83277, 0.83162, 0.52356], - [0.83664, 0.8355, 0.52546], - [0.8406, 0.83947, 0.52754], - [0.84463, 0.84352, 0.52983], - [0.84875, 0.84765, 0.53231], - [0.85294, 0.85185, 0.53497], - [0.85719, 0.85612, 0.53784], - [0.86151, 0.86045, 0.54089], - [0.86589, 0.86483, 0.54413], - [0.87031, 0.86927, 0.54755], - [0.87477, 0.87373, 0.55115], - [0.87927, 0.87824, 0.55492], - [0.88379, 0.88276, 0.55886], - [0.88833, 0.88731, 0.56296], - [0.89287, 0.89186, 0.56721], - [0.89743, 0.89642, 0.5716], - [0.90197, 0.90097, 0.57613], - [0.9065, 0.90551, 0.58077], - [0.91101, 0.91004, 0.58554], - [0.9155, 0.91453, 0.5904], - [0.91996, 0.919, 0.59537], - [0.92438, 0.92344, 0.60043], - [0.92876, 0.92784, 0.60556], - [0.9331, 0.9322, 0.61078], - [0.9374, 0.93652, 0.61605], - [0.94164, 0.94079, 0.62138], - [0.94584, 0.94502, 0.62676], - [0.94999, 0.9492, 0.63218], - [0.95409, 0.95334, 0.63764], - [0.95813, 0.95742, 0.64313], - [0.96213, 0.96146, 0.64864], - [0.96608, 0.96546, 0.65418], - [0.96998, 0.96942, 0.65974], - [0.97384, 0.97334, 0.66532], - [0.97766, 0.97722, 0.67091], - [0.98144, 0.98106, 0.67651], - [0.98519, 0.98488, 0.68211], - [0.9889, 0.98867, 0.68773], - [0.99259, 0.99243, 0.69335], - [0.99624, 0.99617, 0.69898], -]; - -export const colormap_oleron_data: Array<[number, number, number]> = [ - [0.10105, 0.15003, 0.35027], - [0.10721, 0.15579, 0.35609], - [0.11329, 0.16159, 0.36192], - [0.11927, 0.16739, 0.36777], - [0.12525, 0.17322, 0.37365], - [0.13122, 0.17911, 0.37954], - [0.13717, 0.18502, 0.38546], - [0.1431, 0.19093, 0.39141], - [0.14904, 0.19692, 0.39737], - [0.15498, 0.20288, 0.40336], - [0.16095, 0.20889, 0.40937], - [0.16694, 0.21492, 0.4154], - [0.17291, 0.22102, 0.42146], - [0.17894, 0.22709, 0.42756], - [0.18498, 0.23318, 0.43365], - [0.19102, 0.23934, 0.43979], - [0.19712, 0.24548, 0.44594], - [0.20322, 0.25169, 0.45213], - [0.20936, 0.25788, 0.45832], - [0.21553, 0.26413, 0.46456], - [0.22171, 0.27039, 0.4708], - [0.22794, 0.27666, 0.47706], - [0.23417, 0.28297, 0.48335], - [0.24042, 0.28929, 0.48967], - [0.24672, 0.29562, 0.496], - [0.25305, 0.30198, 0.50237], - [0.25939, 0.30838, 0.50876], - [0.26575, 0.31478, 0.51515], - [0.27212, 0.32122, 0.52157], - [0.27855, 0.32766, 0.52802], - [0.28496, 0.33415, 0.53448], - [0.29144, 0.34064, 0.54097], - [0.2979, 0.34716, 0.54747], - [0.3044, 0.35367, 0.554], - [0.31094, 0.36022, 0.56055], - [0.31747, 0.36681, 0.56712], - [0.32403, 0.37339, 0.5737], - [0.33061, 0.38, 0.58031], - [0.33723, 0.38662, 0.58693], - [0.34384, 0.39328, 0.59357], - [0.3505, 0.39994, 0.60023], - [0.35717, 0.40664, 0.60692], - [0.36384, 0.41334, 0.61361], - [0.37054, 0.42006, 0.62034], - [0.37727, 0.42681, 0.62707], - [0.38401, 0.43356, 0.63383], - [0.39077, 0.44034, 0.6406], - [0.39755, 0.44713, 0.64739], - [0.40434, 0.45395, 0.6542], - [0.41116, 0.46078, 0.66102], - [0.41799, 0.46763, 0.66787], - [0.42485, 0.4745, 0.67472], - [0.43173, 0.48137, 0.6816], - [0.4386, 0.48828, 0.6885], - [0.4455, 0.49519, 0.69541], - [0.45244, 0.50212, 0.70234], - [0.45937, 0.50908, 0.70929], - [0.46632, 0.51603, 0.71625], - [0.47329, 0.52302, 0.72322], - [0.48029, 0.53002, 0.73022], - [0.4873, 0.53704, 0.73723], - [0.49432, 0.54406, 0.74425], - [0.50136, 0.55111, 0.7513], - [0.50841, 0.55817, 0.75835], - [0.51547, 0.56524, 0.76542], - [0.52256, 0.57235, 0.7725], - [0.52967, 0.57946, 0.7796], - [0.53679, 0.58658, 0.78671], - [0.54392, 0.59372, 0.79382], - [0.55107, 0.60087, 0.80094], - [0.55822, 0.60804, 0.80806], - [0.5654, 0.61521, 0.81518], - [0.5726, 0.62241, 0.8223], - [0.57981, 0.62961, 0.8294], - [0.58702, 0.63684, 0.83647], - [0.59424, 0.64405, 0.84351], - [0.60147, 0.65129, 0.85051], - [0.60872, 0.65852, 0.85745], - [0.61595, 0.66575, 0.86431], - [0.62318, 0.67298, 0.87109], - [0.6304, 0.68018, 0.87775], - [0.6376, 0.68737, 0.88428], - [0.64477, 0.69453, 0.89065], - [0.65191, 0.70165, 0.89685], - [0.659, 0.70873, 0.90284], - [0.66603, 0.71575, 0.90861], - [0.673, 0.72268, 0.91414], - [0.67987, 0.72954, 0.9194], - [0.68666, 0.7363, 0.92438], - [0.69334, 0.74297, 0.92907], - [0.69991, 0.74951, 0.93347], - [0.70637, 0.75595, 0.93757], - [0.71269, 0.76226, 0.94137], - [0.7189, 0.76845, 0.94489], - [0.72499, 0.77451, 0.94812], - [0.73094, 0.78046, 0.9511], - [0.73679, 0.78631, 0.95383], - [0.74254, 0.79203, 0.95633], - [0.74818, 0.79766, 0.95864], - [0.75373, 0.80321, 0.96077], - [0.7592, 0.80868, 0.96274], - [0.76461, 0.81408, 0.96457], - [0.76995, 0.81943, 0.9663], - [0.77525, 0.82473, 0.96793], - [0.78052, 0.83, 0.96948], - [0.78575, 0.83524, 0.97097], - [0.79096, 0.84045, 0.97241], - [0.79615, 0.84564, 0.97381], - [0.80133, 0.85083, 0.97518], - [0.80651, 0.85602, 0.97653], - [0.81168, 0.86119, 0.97787], - [0.81685, 0.86637, 0.97919], - [0.82203, 0.87155, 0.9805], - [0.8272, 0.87673, 0.98181], - [0.83238, 0.88193, 0.98311], - [0.83757, 0.88712, 0.98442], - [0.84276, 0.89233, 0.98572], - [0.84795, 0.89753, 0.98702], - [0.85315, 0.90275, 0.98831], - [0.85836, 0.90797, 0.98962], - [0.86357, 0.9132, 0.99091], - [0.86879, 0.91844, 0.99221], - [0.874, 0.92368, 0.99351], - [0.87922, 0.92893, 0.9948], - [0.88444, 0.93418, 0.9961], - [0.88967, 0.93945, 0.99739], - [0.89489, 0.94472, 0.99869], - [0.90011, 0.94999, 0.99997], - [0.10024, 0.29901, 0.00015511], - [0.11206, 0.30199, 0.00022614], - [0.12317, 0.30497, 0.00025664], - [0.1339, 0.3079, 0.00024737], - [0.14418, 0.31082, 0.00020433], - [0.15412, 0.31369, 0.00016131], - [0.16383, 0.31653, 0.00012503], - [0.17323, 0.31932, 9.6573e-5], - [0.18245, 0.32208, 7.7354e-5], - [0.19152, 0.3248, 6.932e-5], - [0.2004, 0.32749, 7.5132e-5], - [0.20919, 0.33016, 9.8417e-5], - [0.21784, 0.33279, 0.00014406], - [0.2264, 0.3354, 0.00021853], - [0.23486, 0.33797, 0.00033026], - [0.24321, 0.34055, 0.00049005], - [0.25156, 0.34313, 0.00071147], - [0.25983, 0.34569, 0.0010113], - [0.26806, 0.3483, 0.0014102], - [0.27631, 0.35093, 0.0019325], - [0.28451, 0.35358, 0.0026075], - [0.29274, 0.35632, 0.0034694], - [0.30099, 0.3591, 0.0045572], - [0.3093, 0.36199, 0.005916], - [0.31763, 0.36496, 0.0075965], - [0.32602, 0.36806, 0.009658], - [0.33451, 0.37128, 0.012367], - [0.34305, 0.37466, 0.015348], - [0.35167, 0.37818, 0.01893], - [0.36038, 0.38186, 0.023166], - [0.36919, 0.38571, 0.028136], - [0.37806, 0.38973, 0.033895], - [0.38702, 0.39393, 0.0408], - [0.39605, 0.39829, 0.047888], - [0.40512, 0.4028, 0.055327], - [0.41425, 0.40747, 0.06302], - [0.42339, 0.41228, 0.070789], - [0.43257, 0.41721, 0.078726], - [0.44174, 0.42223, 0.086949], - [0.45088, 0.42738, 0.095228], - [0.46, 0.43259, 0.10362], - [0.4691, 0.43785, 0.11211], - [0.47812, 0.44317, 0.12065], - [0.4871, 0.44852, 0.12932], - [0.49601, 0.45389, 0.13805], - [0.50487, 0.45928, 0.14676], - [0.51366, 0.46468, 0.15555], - [0.52237, 0.47008, 0.16436], - [0.53104, 0.47548, 0.17315], - [0.53964, 0.48087, 0.18196], - [0.5482, 0.48628, 0.1908], - [0.5567, 0.4917, 0.19962], - [0.56516, 0.49712, 0.20847], - [0.57361, 0.50256, 0.21731], - [0.58203, 0.50804, 0.22616], - [0.59044, 0.51354, 0.235], - [0.59885, 0.51909, 0.24381], - [0.60727, 0.52468, 0.25267], - [0.61569, 0.53033, 0.26152], - [0.62414, 0.53605, 0.27039], - [0.63261, 0.54183, 0.27926], - [0.64111, 0.54769, 0.28812], - [0.64966, 0.55363, 0.29703], - [0.65823, 0.55966, 0.30594], - [0.66685, 0.56576, 0.31483], - [0.67551, 0.57195, 0.32377], - [0.6842, 0.57822, 0.33273], - [0.69296, 0.58458, 0.34168], - [0.70173, 0.591, 0.35066], - [0.71056, 0.59751, 0.35964], - [0.71941, 0.60408, 0.36865], - [0.7283, 0.61071, 0.37767], - [0.73722, 0.6174, 0.3867], - [0.74616, 0.62415, 0.39577], - [0.75513, 0.63095, 0.40484], - [0.76411, 0.63778, 0.41394], - [0.77309, 0.64467, 0.42306], - [0.78209, 0.6516, 0.43223], - [0.79107, 0.65857, 0.44141], - [0.80005, 0.66558, 0.45063], - [0.809, 0.67262, 0.45989], - [0.81789, 0.6797, 0.46922], - [0.82674, 0.68682, 0.47857], - [0.83551, 0.69397, 0.48799], - [0.84419, 0.70116, 0.49746], - [0.85274, 0.70839, 0.50699], - [0.86114, 0.71565, 0.51658], - [0.86936, 0.72293, 0.52624], - [0.87737, 0.73025, 0.53595], - [0.88513, 0.73757, 0.54572], - [0.89262, 0.74491, 0.55551], - [0.89981, 0.75225, 0.56535], - [0.90665, 0.75957, 0.57522], - [0.91313, 0.76687, 0.58508], - [0.91921, 0.77413, 0.59493], - [0.92491, 0.78136, 0.60476], - [0.9302, 0.78851, 0.61454], - [0.93507, 0.7956, 0.62429], - [0.93954, 0.80262, 0.63396], - [0.94361, 0.80956, 0.64355], - [0.94731, 0.81641, 0.65307], - [0.95066, 0.82318, 0.66252], - [0.95369, 0.82988, 0.67188], - [0.95641, 0.8365, 0.68116], - [0.95888, 0.84305, 0.69039], - [0.96112, 0.84954, 0.69955], - [0.96316, 0.85598, 0.70866], - [0.96502, 0.86239, 0.71773], - [0.96675, 0.86875, 0.72676], - [0.96835, 0.87509, 0.73578], - [0.96986, 0.88142, 0.74478], - [0.9713, 0.88773, 0.75378], - [0.97268, 0.89405, 0.76277], - [0.974, 0.90036, 0.77179], - [0.97529, 0.90668, 0.78081], - [0.97655, 0.91301, 0.78985], - [0.97779, 0.91936, 0.79891], - [0.97902, 0.92572, 0.80799], - [0.98023, 0.93209, 0.8171], - [0.98143, 0.93848, 0.82624], - [0.98261, 0.94489, 0.8354], - [0.98378, 0.95132, 0.84459], - [0.98495, 0.95776, 0.8538], - [0.98609, 0.96422, 0.86304], - [0.98722, 0.97069, 0.87231], - [0.98833, 0.97718, 0.88159], - [0.98942, 0.98369, 0.8909], - [0.99049, 0.9902, 0.90023], -]; - -export const colormap_oslo_data: Array<[number, number, number]> = [ - [0.0036704, 0.0050824, 0.0024536], - [0.0056626, 0.0093944, 0.010695], - [0.0076737, 0.0139, 0.019154], - [0.0097079, 0.018228, 0.027418], - [0.011981, 0.022573, 0.035904], - [0.01404, 0.026935, 0.043975], - [0.01615, 0.031315, 0.05138], - [0.018294, 0.035927, 0.058123], - [0.020473, 0.040333, 0.064433], - [0.022689, 0.044608, 0.070257], - [0.024947, 0.048672, 0.075728], - [0.027247, 0.052453, 0.080952], - [0.029592, 0.05624, 0.085837], - [0.031984, 0.059842, 0.090619], - [0.034477, 0.063258, 0.095163], - [0.037057, 0.066553, 0.09953], - [0.039346, 0.06983, 0.104], - [0.041492, 0.072993, 0.10848], - [0.043238, 0.076022, 0.1131], - [0.045051, 0.079044, 0.11765], - [0.046508, 0.082102, 0.12227], - [0.047784, 0.084964, 0.12697], - [0.049035, 0.087853, 0.13174], - [0.049925, 0.09066, 0.13649], - [0.050671, 0.093388, 0.14135], - [0.051245, 0.096126, 0.14619], - [0.051698, 0.098921, 0.15108], - [0.05216, 0.10171, 0.15603], - [0.052632, 0.10451, 0.16098], - [0.053115, 0.10741, 0.16595], - [0.053612, 0.11032, 0.17099], - [0.054125, 0.11324, 0.17602], - [0.054655, 0.11618, 0.18112], - [0.055201, 0.11913, 0.18627], - [0.055777, 0.12209, 0.1914], - [0.056384, 0.12516, 0.19661], - [0.056955, 0.12823, 0.20178], - [0.057498, 0.13131, 0.20704], - [0.058136, 0.13444, 0.2123], - [0.058867, 0.13757, 0.21759], - [0.059601, 0.14073, 0.22291], - [0.060281, 0.14391, 0.22826], - [0.060943, 0.14711, 0.2336], - [0.061699, 0.15035, 0.23901], - [0.062585, 0.15358, 0.24441], - [0.063381, 0.15688, 0.24986], - [0.064199, 0.16015, 0.25535], - [0.065067, 0.16352, 0.26083], - [0.065965, 0.16686, 0.26635], - [0.066906, 0.1702, 0.27186], - [0.06788, 0.17357, 0.27744], - [0.068913, 0.17697, 0.28302], - [0.069887, 0.18038, 0.28861], - [0.070924, 0.18381, 0.29422], - [0.071974, 0.18728, 0.29987], - [0.073118, 0.19072, 0.30554], - [0.074222, 0.19423, 0.31121], - [0.075341, 0.1977, 0.31691], - [0.076503, 0.20119, 0.32264], - [0.077709, 0.20473, 0.32836], - [0.078959, 0.20826, 0.33412], - [0.080255, 0.21181, 0.33989], - [0.081609, 0.21535, 0.34567], - [0.082887, 0.21892, 0.35147], - [0.084299, 0.22249, 0.35731], - [0.085598, 0.22609, 0.36313], - [0.087109, 0.22965, 0.36899], - [0.088529, 0.23325, 0.37486], - [0.090015, 0.2369, 0.38075], - [0.091564, 0.24048, 0.38663], - [0.093033, 0.2441, 0.39255], - [0.094704, 0.24776, 0.39848], - [0.096248, 0.2514, 0.40442], - [0.097979, 0.25504, 0.41039], - [0.099642, 0.25867, 0.41635], - [0.10138, 0.26232, 0.42232], - [0.1032, 0.26598, 0.42833], - [0.10497, 0.26965, 0.43433], - [0.10692, 0.27331, 0.44035], - [0.10879, 0.27697, 0.44639], - [0.1108, 0.28062, 0.45244], - [0.11283, 0.28431, 0.45849], - [0.11484, 0.28799, 0.46456], - [0.11699, 0.29169, 0.47064], - [0.11919, 0.29536, 0.47672], - [0.1214, 0.29907, 0.48282], - [0.12371, 0.30275, 0.48893], - [0.12613, 0.30647, 0.49506], - [0.12854, 0.31018, 0.50119], - [0.13107, 0.31389, 0.50733], - [0.13364, 0.31762, 0.51348], - [0.13625, 0.32135, 0.51964], - [0.139, 0.32509, 0.52582], - [0.14184, 0.32887, 0.532], - [0.14474, 0.33265, 0.5382], - [0.14772, 0.33642, 0.5444], - [0.15079, 0.34023, 0.55062], - [0.15395, 0.34405, 0.55685], - [0.15723, 0.34791, 0.56308], - [0.16061, 0.35178, 0.56932], - [0.16413, 0.3557, 0.57558], - [0.16771, 0.35962, 0.58184], - [0.17142, 0.36359, 0.58811], - [0.17526, 0.36759, 0.59439], - [0.17923, 0.37163, 0.60067], - [0.1833, 0.37572, 0.60697], - [0.18756, 0.37985, 0.61324], - [0.19189, 0.38402, 0.61953], - [0.19642, 0.38824, 0.6258], - [0.20102, 0.39251, 0.63207], - [0.20583, 0.39683, 0.63832], - [0.21074, 0.40122, 0.64454], - [0.21582, 0.40565, 0.65075], - [0.22103, 0.41013, 0.65692], - [0.22637, 0.41465, 0.66304], - [0.23185, 0.41923, 0.6691], - [0.23747, 0.42385, 0.67511], - [0.24318, 0.42853, 0.68103], - [0.24906, 0.43324, 0.68689], - [0.25504, 0.438, 0.69265], - [0.26109, 0.44277, 0.6983], - [0.26724, 0.44756, 0.70383], - [0.27351, 0.4524, 0.70924], - [0.27982, 0.45722, 0.7145], - [0.28617, 0.46205, 0.71962], - [0.29259, 0.46688, 0.72457], - [0.29905, 0.47169, 0.72935], - [0.30552, 0.47648, 0.73395], - [0.31196, 0.48123, 0.73836], - [0.31844, 0.48596, 0.74258], - [0.32488, 0.49065, 0.74659], - [0.33129, 0.49527, 0.7504], - [0.33767, 0.49983, 0.75401], - [0.34399, 0.50435, 0.75741], - [0.35027, 0.50878, 0.7606], - [0.35647, 0.51314, 0.76358], - [0.3626, 0.51744, 0.76637], - [0.36866, 0.52164, 0.76895], - [0.37464, 0.52578, 0.77135], - [0.38054, 0.52984, 0.77355], - [0.38634, 0.53381, 0.77557], - [0.39208, 0.53772, 0.77743], - [0.39773, 0.54152, 0.77911], - [0.4033, 0.54528, 0.78064], - [0.40879, 0.54895, 0.78202], - [0.4142, 0.55255, 0.78326], - [0.41955, 0.55607, 0.78438], - [0.42482, 0.55955, 0.78536], - [0.43003, 0.56296, 0.78624], - [0.43518, 0.56631, 0.78702], - [0.44025, 0.56961, 0.78769], - [0.44529, 0.57287, 0.78828], - [0.45027, 0.57608, 0.78879], - [0.45521, 0.57923, 0.78922], - [0.4601, 0.58235, 0.78958], - [0.46496, 0.58545, 0.78988], - [0.46979, 0.5885, 0.79013], - [0.47458, 0.59153, 0.79033], - [0.47934, 0.59453, 0.79049], - [0.48408, 0.59752, 0.7906], - [0.4888, 0.60047, 0.79068], - [0.4935, 0.60342, 0.79073], - [0.4982, 0.60634, 0.79076], - [0.50285, 0.60926, 0.79075], - [0.50752, 0.61215, 0.79073], - [0.51216, 0.61504, 0.79069], - [0.51681, 0.61793, 0.79063], - [0.52144, 0.62081, 0.79057], - [0.52608, 0.62368, 0.79049], - [0.5307, 0.62654, 0.7904], - [0.53532, 0.6294, 0.79031], - [0.53994, 0.63227, 0.79021], - [0.54457, 0.63513, 0.79011], - [0.5492, 0.638, 0.79001], - [0.55382, 0.64086, 0.78991], - [0.55845, 0.64373, 0.78981], - [0.5631, 0.64661, 0.78972], - [0.56773, 0.64949, 0.78964], - [0.57238, 0.65238, 0.78956], - [0.57704, 0.65527, 0.7895], - [0.58169, 0.65818, 0.78944], - [0.58637, 0.66109, 0.7894], - [0.59105, 0.66403, 0.78938], - [0.59574, 0.66696, 0.78937], - [0.60044, 0.66993, 0.78938], - [0.60516, 0.6729, 0.78942], - [0.60989, 0.67589, 0.78948], - [0.61464, 0.67891, 0.78957], - [0.61941, 0.68194, 0.78969], - [0.62419, 0.68501, 0.78985], - [0.62899, 0.6881, 0.79004], - [0.63382, 0.69121, 0.79027], - [0.63866, 0.69435, 0.79055], - [0.64352, 0.69754, 0.79087], - [0.64842, 0.70076, 0.79124], - [0.65334, 0.70401, 0.79167], - [0.65829, 0.70731, 0.79216], - [0.66327, 0.71065, 0.79272], - [0.66828, 0.71403, 0.79334], - [0.67332, 0.71747, 0.79403], - [0.6784, 0.72094, 0.79479], - [0.68351, 0.72448, 0.79564], - [0.68866, 0.72807, 0.79657], - [0.69384, 0.73173, 0.79759], - [0.69907, 0.73544, 0.79871], - [0.70433, 0.73922, 0.79993], - [0.70964, 0.74305, 0.80124], - [0.71499, 0.74695, 0.80266], - [0.72038, 0.75093, 0.8042], - [0.72581, 0.75497, 0.80584], - [0.73128, 0.75908, 0.80761], - [0.73679, 0.76326, 0.80949], - [0.74235, 0.76752, 0.8115], - [0.74795, 0.77185, 0.81362], - [0.75358, 0.77626, 0.81589], - [0.75926, 0.78073, 0.81827], - [0.76498, 0.78528, 0.8208], - [0.77073, 0.7899, 0.82345], - [0.77651, 0.7946, 0.82624], - [0.78233, 0.79936, 0.82916], - [0.78818, 0.80419, 0.83221], - [0.79406, 0.8091, 0.83539], - [0.79997, 0.81406, 0.8387], - [0.8059, 0.81908, 0.84215], - [0.81186, 0.82418, 0.84572], - [0.81783, 0.82933, 0.84942], - [0.82383, 0.83454, 0.85323], - [0.82985, 0.8398, 0.85717], - [0.83587, 0.84511, 0.86123], - [0.84192, 0.85047, 0.8654], - [0.84796, 0.85588, 0.86968], - [0.85402, 0.86133, 0.87406], - [0.8601, 0.86682, 0.87855], - [0.86617, 0.87236, 0.88313], - [0.87225, 0.87793, 0.88781], - [0.87832, 0.88353, 0.89257], - [0.88441, 0.88917, 0.89742], - [0.89049, 0.89484, 0.90235], - [0.89657, 0.90052, 0.90736], - [0.90265, 0.90624, 0.91243], - [0.90873, 0.91198, 0.91758], - [0.91481, 0.91775, 0.92278], - [0.92088, 0.92353, 0.92804], - [0.92695, 0.92933, 0.93336], - [0.93302, 0.93515, 0.93873], - [0.9391, 0.94098, 0.94414], - [0.94517, 0.94683, 0.94959], - [0.95123, 0.9527, 0.95509], - [0.9573, 0.95858, 0.96061], - [0.96337, 0.96446, 0.96617], - [0.96943, 0.97036, 0.97175], - [0.9755, 0.97627, 0.97736], - [0.98157, 0.9822, 0.98298], - [0.98765, 0.98813, 0.98863], - [0.99372, 0.99407, 0.99429], - [0.9998, 1, 0.99996], -]; - -export const colormap_roma_data: Array<[number, number, number]> = [ - [0.49684, 0.099626, 0], - [0.50141, 0.11159, 0.0038271], - [0.50595, 0.12281, 0.0075362], - [0.51049, 0.13362, 0.011176], - [0.51502, 0.14397, 0.014691], - [0.51953, 0.15397, 0.017936], - [0.52403, 0.16373, 0.02102], - [0.52851, 0.17319, 0.023941], - [0.53298, 0.18247, 0.026768], - [0.53742, 0.19159, 0.02974], - [0.54181, 0.20053, 0.032886], - [0.5462, 0.20938, 0.036371], - [0.55055, 0.2181, 0.03985], - [0.55486, 0.22671, 0.043275], - [0.55915, 0.23522, 0.046908], - [0.56342, 0.24362, 0.050381], - [0.56764, 0.25199, 0.053844], - [0.57184, 0.26026, 0.057332], - [0.57601, 0.26848, 0.06081], - [0.58015, 0.27665, 0.064287], - [0.58425, 0.28474, 0.067738], - [0.58833, 0.29281, 0.071178], - [0.59239, 0.30083, 0.074547], - [0.59641, 0.30883, 0.077891], - [0.60041, 0.31677, 0.081344], - [0.60439, 0.32468, 0.084709], - [0.60834, 0.33258, 0.088059], - [0.61225, 0.34043, 0.091425], - [0.61616, 0.34827, 0.094762], - [0.62004, 0.35608, 0.098071], - [0.6239, 0.36387, 0.10135], - [0.62774, 0.37164, 0.10462], - [0.63157, 0.37941, 0.10794], - [0.63537, 0.38716, 0.11129], - [0.63916, 0.3949, 0.11452], - [0.64294, 0.40263, 0.11786], - [0.64671, 0.41037, 0.12112], - [0.65046, 0.41807, 0.12443], - [0.65421, 0.42579, 0.12776], - [0.65795, 0.43351, 0.13108], - [0.66169, 0.44123, 0.13442], - [0.66541, 0.44896, 0.13776], - [0.66914, 0.45668, 0.14112], - [0.67287, 0.46443, 0.1445], - [0.6766, 0.47218, 0.1479], - [0.68033, 0.47994, 0.15134], - [0.68407, 0.48772, 0.15484], - [0.68783, 0.49551, 0.1584], - [0.69159, 0.50332, 0.162], - [0.69537, 0.51117, 0.1656], - [0.69916, 0.51905, 0.16938], - [0.70298, 0.52695, 0.17315], - [0.70681, 0.53488, 0.17706], - [0.71067, 0.54285, 0.18103], - [0.71456, 0.55087, 0.18517], - [0.71848, 0.55892, 0.18939], - [0.72244, 0.56704, 0.19377], - [0.72644, 0.57519, 0.19826], - [0.73049, 0.5834, 0.20295], - [0.73457, 0.59168, 0.20781], - [0.7387, 0.60002, 0.21285], - [0.74289, 0.60842, 0.21813], - [0.74712, 0.61688, 0.22361], - [0.75142, 0.6254, 0.22933], - [0.75576, 0.634, 0.23533], - [0.76016, 0.64265, 0.24156], - [0.76463, 0.65137, 0.24809], - [0.76914, 0.66014, 0.2549], - [0.77371, 0.66897, 0.262], - [0.77833, 0.67784, 0.26943], - [0.783, 0.68674, 0.27716], - [0.78771, 0.69568, 0.2852], - [0.79246, 0.70462, 0.29358], - [0.79722, 0.71357, 0.30227], - [0.80201, 0.72249, 0.31128], - [0.80681, 0.73138, 0.32059], - [0.81159, 0.74021, 0.33017], - [0.81635, 0.74896, 0.34004], - [0.82108, 0.75761, 0.35015], - [0.82576, 0.76614, 0.36047], - [0.83037, 0.77452, 0.37103], - [0.8349, 0.78274, 0.38176], - [0.83934, 0.79077, 0.39264], - [0.84366, 0.7986, 0.40365], - [0.84785, 0.80619, 0.41475], - [0.8519, 0.81354, 0.42591], - [0.8558, 0.82064, 0.43711], - [0.85953, 0.82748, 0.44831], - [0.86308, 0.83404, 0.4595], - [0.86643, 0.84031, 0.47065], - [0.86958, 0.84629, 0.48173], - [0.87253, 0.85199, 0.49272], - [0.87526, 0.8574, 0.50362], - [0.87777, 0.86254, 0.51441], - [0.88004, 0.86739, 0.52506], - [0.88209, 0.87197, 0.53557], - [0.8839, 0.87629, 0.54595], - [0.88546, 0.88035, 0.55615], - [0.88677, 0.88417, 0.56622], - [0.88783, 0.88775, 0.57613], - [0.88864, 0.89111, 0.58587], - [0.88918, 0.89426, 0.59544], - [0.88946, 0.8972, 0.60485], - [0.88947, 0.89994, 0.61409], - [0.88921, 0.9025, 0.62319], - [0.88867, 0.90488, 0.6321], - [0.88785, 0.90709, 0.64085], - [0.88674, 0.90914, 0.64945], - [0.88534, 0.91104, 0.65787], - [0.88364, 0.91279, 0.66612], - [0.88165, 0.9144, 0.67421], - [0.87934, 0.91587, 0.68212], - [0.87673, 0.91722, 0.68988], - [0.87381, 0.91842, 0.69745], - [0.87058, 0.9195, 0.70485], - [0.86703, 0.92046, 0.71207], - [0.86316, 0.92129, 0.71912], - [0.85897, 0.92201, 0.72598], - [0.85447, 0.9226, 0.73266], - [0.84965, 0.92307, 0.73915], - [0.84452, 0.92342, 0.74544], - [0.83906, 0.92365, 0.75155], - [0.8333, 0.92375, 0.75746], - [0.82723, 0.92373, 0.76318], - [0.82086, 0.92358, 0.7687], - [0.81418, 0.9233, 0.77403], - [0.80722, 0.92289, 0.77916], - [0.79997, 0.92234, 0.7841], - [0.79243, 0.92166, 0.78883], - [0.78462, 0.92082, 0.79337], - [0.77654, 0.91986, 0.79771], - [0.7682, 0.91873, 0.80185], - [0.7596, 0.91747, 0.80581], - [0.75077, 0.91603, 0.80957], - [0.74169, 0.91444, 0.81313], - [0.7324, 0.91268, 0.81651], - [0.72287, 0.91075, 0.8197], - [0.71314, 0.90865, 0.8227], - [0.70322, 0.90636, 0.82551], - [0.69311, 0.90389, 0.82814], - [0.68283, 0.90124, 0.83059], - [0.67239, 0.89839, 0.83284], - [0.6618, 0.89535, 0.83492], - [0.65107, 0.89211, 0.83682], - [0.64024, 0.88868, 0.83853], - [0.6293, 0.88504, 0.84006], - [0.61828, 0.8812, 0.84141], - [0.60721, 0.87716, 0.84258], - [0.59608, 0.87292, 0.84357], - [0.58494, 0.86849, 0.84438], - [0.57379, 0.86386, 0.84502], - [0.56267, 0.85903, 0.84548], - [0.55159, 0.85402, 0.84576], - [0.54058, 0.84884, 0.84588], - [0.52966, 0.84347, 0.84582], - [0.51886, 0.83795, 0.8456], - [0.50819, 0.83227, 0.84522], - [0.49767, 0.82643, 0.84467], - [0.48733, 0.82046, 0.84397], - [0.47718, 0.81436, 0.84312], - [0.46725, 0.80814, 0.84213], - [0.45755, 0.8018, 0.84099], - [0.44809, 0.79537, 0.83973], - [0.43889, 0.78885, 0.83833], - [0.42997, 0.78225, 0.83681], - [0.42131, 0.77557, 0.83517], - [0.41296, 0.76883, 0.83343], - [0.40486, 0.76204, 0.83159], - [0.39707, 0.75521, 0.82964], - [0.38957, 0.74833, 0.82761], - [0.38235, 0.74142, 0.82549], - [0.37542, 0.7345, 0.8233], - [0.36877, 0.72754, 0.82104], - [0.36238, 0.72058, 0.8187], - [0.35627, 0.71361, 0.81632], - [0.3504, 0.70664, 0.81387], - [0.34477, 0.69966, 0.81138], - [0.33939, 0.69269, 0.80884], - [0.33422, 0.68572, 0.80626], - [0.32926, 0.67875, 0.80364], - [0.32448, 0.67181, 0.801], - [0.31992, 0.66486, 0.79832], - [0.31551, 0.65795, 0.79562], - [0.31127, 0.65104, 0.7929], - [0.30718, 0.64414, 0.79015], - [0.30322, 0.63727, 0.78739], - [0.29942, 0.63042, 0.78462], - [0.29571, 0.62358, 0.78184], - [0.29213, 0.61676, 0.77904], - [0.28864, 0.60995, 0.77624], - [0.28523, 0.60318, 0.77343], - [0.28193, 0.59642, 0.77063], - [0.2787, 0.58967, 0.76781], - [0.27554, 0.58296, 0.765], - [0.27241, 0.57628, 0.76218], - [0.26939, 0.56959, 0.75937], - [0.26638, 0.56295, 0.75656], - [0.26345, 0.5563, 0.75375], - [0.26053, 0.5497, 0.75095], - [0.25766, 0.54311, 0.74814], - [0.25486, 0.53655, 0.74534], - [0.25205, 0.53, 0.74255], - [0.24928, 0.52347, 0.73977], - [0.24654, 0.51697, 0.73698], - [0.24382, 0.51048, 0.73421], - [0.24114, 0.50402, 0.73143], - [0.23846, 0.49758, 0.72867], - [0.23583, 0.49117, 0.72592], - [0.23317, 0.48475, 0.72317], - [0.23056, 0.47838, 0.72043], - [0.22798, 0.47202, 0.7177], - [0.22538, 0.46567, 0.71496], - [0.22282, 0.45936, 0.71224], - [0.22026, 0.45306, 0.70953], - [0.2177, 0.44678, 0.70682], - [0.21514, 0.44051, 0.70412], - [0.21262, 0.43427, 0.70142], - [0.21009, 0.42806, 0.69874], - [0.20758, 0.42184, 0.69606], - [0.20507, 0.41566, 0.69339], - [0.20256, 0.4095, 0.69071], - [0.20005, 0.40335, 0.68806], - [0.19757, 0.3972, 0.6854], - [0.19509, 0.3911, 0.68275], - [0.19259, 0.38498, 0.6801], - [0.1901, 0.3789, 0.67748], - [0.18765, 0.37283, 0.67484], - [0.18515, 0.36678, 0.67222], - [0.18262, 0.36073, 0.66959], - [0.18013, 0.35472, 0.66697], - [0.17766, 0.3487, 0.66436], - [0.17513, 0.34271, 0.66176], - [0.17259, 0.33671, 0.65915], - [0.17007, 0.33072, 0.65656], - [0.16752, 0.32475, 0.65396], - [0.16494, 0.3188, 0.65137], - [0.16238, 0.31285, 0.64878], - [0.15974, 0.30691, 0.64619], - [0.15712, 0.30097, 0.64361], - [0.15446, 0.29504, 0.64103], - [0.15176, 0.28914, 0.63846], - [0.14904, 0.28322, 0.63589], - [0.14627, 0.2773, 0.63331], - [0.14346, 0.27138, 0.63075], - [0.1406, 0.26547, 0.62818], - [0.13769, 0.25957, 0.62561], - [0.1347, 0.25365, 0.62305], - [0.13163, 0.24774, 0.62049], - [0.12849, 0.24182, 0.61792], - [0.12528, 0.2359, 0.61535], - [0.12194, 0.22993, 0.61279], - [0.11859, 0.22399, 0.61023], - [0.11502, 0.21805, 0.60768], - [0.11142, 0.21209, 0.60511], - [0.10761, 0.20611, 0.60255], - [0.1037, 0.20006, 0.59999], -]; - -export const colormap_romao_data: Array<[number, number, number]> = [ - [0.45137, 0.22346, 0.34187], - [0.45418, 0.22244, 0.3361], - [0.45696, 0.22158, 0.33043], - [0.45975, 0.2209, 0.32483], - [0.46251, 0.22035, 0.31935], - [0.46527, 0.21994, 0.31394], - [0.46803, 0.21968, 0.30862], - [0.47078, 0.21958, 0.30337], - [0.47352, 0.21962, 0.29822], - [0.47628, 0.21982, 0.29316], - [0.47902, 0.22017, 0.28818], - [0.48178, 0.22067, 0.2833], - [0.48453, 0.2213, 0.2785], - [0.48731, 0.22208, 0.27379], - [0.49008, 0.22304, 0.26917], - [0.49286, 0.22411, 0.26461], - [0.49567, 0.22536, 0.26016], - [0.4985, 0.22677, 0.25579], - [0.50134, 0.22833, 0.25153], - [0.50419, 0.22999, 0.24733], - [0.50707, 0.23188, 0.24322], - [0.50997, 0.23387, 0.23923], - [0.5129, 0.23605, 0.23533], - [0.51584, 0.23835, 0.23151], - [0.51884, 0.24082, 0.22779], - [0.52184, 0.24345, 0.22414], - [0.52489, 0.24625, 0.22065], - [0.52797, 0.2492, 0.2172], - [0.53108, 0.25231, 0.21387], - [0.53423, 0.25556, 0.21064], - [0.53742, 0.25899, 0.20753], - [0.54063, 0.26255, 0.20452], - [0.54389, 0.26628, 0.20158], - [0.54718, 0.27017, 0.19879], - [0.55051, 0.27419, 0.19613], - [0.55389, 0.27839, 0.19356], - [0.55731, 0.28273, 0.19109], - [0.56075, 0.2872, 0.18877], - [0.56424, 0.29186, 0.18655], - [0.56777, 0.29665, 0.18446], - [0.57134, 0.30157, 0.18248], - [0.57495, 0.30666, 0.18065], - [0.5786, 0.31186, 0.17898], - [0.58228, 0.31724, 0.17743], - [0.58602, 0.32275, 0.17597], - [0.58977, 0.32838, 0.17473], - [0.59358, 0.33415, 0.17358], - [0.59742, 0.34005, 0.17261], - [0.60129, 0.34606, 0.17179], - [0.60519, 0.35223, 0.17114], - [0.60915, 0.35851, 0.17065], - [0.61311, 0.36491, 0.17034], - [0.61713, 0.37143, 0.1702], - [0.62118, 0.37808, 0.17023], - [0.62526, 0.38483, 0.17046], - [0.62937, 0.39171, 0.17087], - [0.63352, 0.39869, 0.17148], - [0.63769, 0.40579, 0.17229], - [0.6419, 0.41299, 0.17332], - [0.64613, 0.42029, 0.17458], - [0.65041, 0.42771, 0.176], - [0.6547, 0.43522, 0.17774], - [0.65904, 0.44283, 0.17962], - [0.66341, 0.45054, 0.18175], - [0.6678, 0.45834, 0.18416], - [0.67222, 0.46625, 0.1868], - [0.67667, 0.47425, 0.18968], - [0.68114, 0.48233, 0.19283], - [0.68566, 0.49051, 0.19624], - [0.69019, 0.49878, 0.19987], - [0.69474, 0.50712, 0.20384], - [0.69933, 0.51554, 0.20803], - [0.70394, 0.52406, 0.21251], - [0.70858, 0.53265, 0.21726], - [0.71322, 0.5413, 0.22229], - [0.7179, 0.55003, 0.22761], - [0.72257, 0.55881, 0.23318], - [0.72727, 0.56767, 0.23907], - [0.73197, 0.57658, 0.24521], - [0.73666, 0.58553, 0.25168], - [0.74136, 0.59451, 0.25837], - [0.74605, 0.60354, 0.26537], - [0.75073, 0.61259, 0.27263], - [0.75538, 0.62166, 0.28017], - [0.76001, 0.63075, 0.28796], - [0.7646, 0.63982, 0.29602], - [0.76914, 0.64889, 0.30433], - [0.77363, 0.65793, 0.31287], - [0.77806, 0.66694, 0.32165], - [0.78242, 0.6759, 0.33066], - [0.78669, 0.68481, 0.33988], - [0.79087, 0.69365, 0.34929], - [0.79494, 0.7024, 0.35888], - [0.7989, 0.71106, 0.36867], - [0.80273, 0.71961, 0.37859], - [0.80642, 0.72803, 0.38866], - [0.80996, 0.73631, 0.39885], - [0.81334, 0.74446, 0.40916], - [0.81655, 0.75244, 0.41957], - [0.81956, 0.76025, 0.43004], - [0.82239, 0.76787, 0.44057], - [0.82501, 0.7753, 0.45115], - [0.82742, 0.78252, 0.46174], - [0.8296, 0.78953, 0.47235], - [0.83155, 0.79631, 0.48293], - [0.83326, 0.80287, 0.49349], - [0.83472, 0.80919, 0.50402], - [0.83592, 0.81526, 0.51449], - [0.83686, 0.82109, 0.52487], - [0.83753, 0.82666, 0.53517], - [0.83793, 0.83198, 0.54537], - [0.83805, 0.83703, 0.55546], - [0.83788, 0.84182, 0.56542], - [0.83744, 0.84635, 0.57525], - [0.8367, 0.85061, 0.58493], - [0.83567, 0.85462, 0.59446], - [0.83435, 0.85835, 0.60382], - [0.83274, 0.86183, 0.61301], - [0.83084, 0.86504, 0.62202], - [0.82864, 0.868, 0.63085], - [0.82615, 0.87068, 0.63949], - [0.82337, 0.87312, 0.64792], - [0.8203, 0.87531, 0.65617], - [0.81695, 0.87724, 0.6642], - [0.81331, 0.87892, 0.67203], - [0.80939, 0.88036, 0.67964], - [0.80518, 0.88156, 0.68705], - [0.80071, 0.8825, 0.69424], - [0.79595, 0.88322, 0.70121], - [0.79094, 0.8837, 0.70797], - [0.78566, 0.88395, 0.7145], - [0.78012, 0.88396, 0.72082], - [0.77433, 0.88375, 0.72692], - [0.7683, 0.88331, 0.73279], - [0.76203, 0.88264, 0.73844], - [0.75553, 0.88177, 0.74387], - [0.74879, 0.88066, 0.74908], - [0.74184, 0.87934, 0.75407], - [0.73468, 0.87781, 0.75884], - [0.72731, 0.87607, 0.76339], - [0.71976, 0.87411, 0.76772], - [0.71201, 0.87195, 0.77184], - [0.70408, 0.86958, 0.77573], - [0.69599, 0.86701, 0.77941], - [0.68774, 0.86425, 0.78288], - [0.67934, 0.86127, 0.78614], - [0.67081, 0.85811, 0.78919], - [0.66215, 0.85476, 0.79202], - [0.65336, 0.8512, 0.79465], - [0.64448, 0.84747, 0.79707], - [0.6355, 0.84356, 0.7993], - [0.62645, 0.83947, 0.80131], - [0.61732, 0.83519, 0.80313], - [0.60814, 0.83075, 0.80476], - [0.59891, 0.82614, 0.80619], - [0.58965, 0.82137, 0.80743], - [0.58037, 0.81644, 0.80848], - [0.57108, 0.81135, 0.80935], - [0.56181, 0.80612, 0.81004], - [0.55255, 0.80074, 0.81055], - [0.54332, 0.79522, 0.81088], - [0.53412, 0.78958, 0.81105], - [0.525, 0.7838, 0.81105], - [0.51593, 0.77791, 0.81088], - [0.50695, 0.77189, 0.81055], - [0.49808, 0.76577, 0.81007], - [0.48928, 0.75954, 0.80944], - [0.48061, 0.75321, 0.80866], - [0.47207, 0.7468, 0.80773], - [0.46365, 0.74029, 0.80667], - [0.45539, 0.7337, 0.80546], - [0.44728, 0.72703, 0.80413], - [0.43934, 0.7203, 0.80266], - [0.43158, 0.7135, 0.80107], - [0.42398, 0.70664, 0.79936], - [0.41658, 0.69971, 0.79752], - [0.40938, 0.69275, 0.79557], - [0.40237, 0.68572, 0.79351], - [0.3956, 0.67865, 0.79133], - [0.38903, 0.67155, 0.78905], - [0.38267, 0.66441, 0.78666], - [0.37656, 0.65724, 0.78416], - [0.37066, 0.65003, 0.78155], - [0.36502, 0.64279, 0.77884], - [0.35961, 0.63552, 0.77604], - [0.35446, 0.62824, 0.77312], - [0.34955, 0.62094, 0.77011], - [0.3449, 0.6136, 0.767], - [0.34051, 0.60625, 0.76378], - [0.33637, 0.59889, 0.76047], - [0.33253, 0.59151, 0.75704], - [0.32893, 0.58412, 0.75351], - [0.32559, 0.57671, 0.74987], - [0.32256, 0.56928, 0.74613], - [0.31978, 0.56186, 0.74228], - [0.31727, 0.55441, 0.7383], - [0.31505, 0.54695, 0.73422], - [0.31311, 0.53948, 0.73002], - [0.31144, 0.53201, 0.72569], - [0.31007, 0.52453, 0.72124], - [0.30897, 0.51704, 0.71667], - [0.30811, 0.50955, 0.71197], - [0.30755, 0.50205, 0.70713], - [0.30726, 0.49456, 0.70216], - [0.30723, 0.48707, 0.69706], - [0.30746, 0.47958, 0.69182], - [0.30795, 0.4721, 0.68643], - [0.3087, 0.46463, 0.6809], - [0.30968, 0.45716, 0.67525], - [0.31088, 0.44973, 0.66944], - [0.31228, 0.44232, 0.6635], - [0.31393, 0.43493, 0.65741], - [0.31578, 0.42758, 0.65118], - [0.3178, 0.42025, 0.64482], - [0.32001, 0.41299, 0.63833], - [0.32238, 0.40577, 0.6317], - [0.32489, 0.39861, 0.62495], - [0.32755, 0.39152, 0.61809], - [0.33035, 0.38448, 0.61111], - [0.33327, 0.37755, 0.60402], - [0.33627, 0.37068, 0.59684], - [0.33939, 0.36392, 0.58955], - [0.34257, 0.35728, 0.58219], - [0.3458, 0.35073, 0.57476], - [0.34912, 0.34428, 0.56727], - [0.35247, 0.33797, 0.55971], - [0.35587, 0.33179, 0.55212], - [0.35927, 0.32574, 0.54448], - [0.36271, 0.31986, 0.53684], - [0.36617, 0.31411, 0.52917], - [0.36961, 0.30852, 0.52148], - [0.37306, 0.30306, 0.51382], - [0.37652, 0.2978, 0.50615], - [0.37994, 0.29269, 0.49854], - [0.38336, 0.28775, 0.49094], - [0.38674, 0.28301, 0.48337], - [0.39011, 0.27842, 0.47586], - [0.39346, 0.27401, 0.4684], - [0.39677, 0.26978, 0.461], - [0.40006, 0.26573, 0.45366], - [0.40333, 0.26185, 0.4464], - [0.40655, 0.25815, 0.43921], - [0.40974, 0.25466, 0.43212], - [0.4129, 0.25132, 0.42509], - [0.41602, 0.24817, 0.41813], - [0.41912, 0.24515, 0.41128], - [0.42218, 0.24235, 0.40451], - [0.42522, 0.23972, 0.39784], - [0.42823, 0.23728, 0.39126], - [0.43121, 0.23498, 0.38475], - [0.43415, 0.23282, 0.37836], - [0.43708, 0.23086, 0.37204], - [0.43998, 0.22907, 0.36583], - [0.44286, 0.22743, 0.3597], - [0.44571, 0.22596, 0.35366], - [0.44855, 0.2246, 0.34773], -]; - -export const colormap_tofino_data: Array<[number, number, number]> = [ - [0.87044, 0.84978, 0.99992], - [0.85983, 0.84232, 0.99532], - [0.84923, 0.83488, 0.99073], - [0.83862, 0.82744, 0.98614], - [0.82803, 0.82001, 0.98155], - [0.81744, 0.8126, 0.97696], - [0.80685, 0.80519, 0.97238], - [0.79627, 0.7978, 0.96779], - [0.7857, 0.79041, 0.9632], - [0.77513, 0.78303, 0.95862], - [0.76458, 0.77566, 0.95404], - [0.75403, 0.76829, 0.94946], - [0.74349, 0.76094, 0.94489], - [0.73296, 0.75358, 0.94031], - [0.72244, 0.74624, 0.93573], - [0.71193, 0.73891, 0.93116], - [0.70143, 0.73157, 0.92659], - [0.69094, 0.72424, 0.92202], - [0.68047, 0.71693, 0.91745], - [0.67001, 0.70961, 0.91288], - [0.65956, 0.70229, 0.90831], - [0.64912, 0.69498, 0.90373], - [0.63869, 0.68767, 0.89915], - [0.62827, 0.68036, 0.89457], - [0.61786, 0.67306, 0.88996], - [0.60747, 0.66575, 0.88535], - [0.59708, 0.65844, 0.88072], - [0.58669, 0.65113, 0.87608], - [0.57633, 0.6438, 0.8714], - [0.56595, 0.63648, 0.86669], - [0.55558, 0.62912, 0.86194], - [0.54523, 0.62176, 0.85713], - [0.53488, 0.61438, 0.85228], - [0.52453, 0.60699, 0.84735], - [0.51419, 0.59956, 0.84234], - [0.50383, 0.5921, 0.83724], - [0.49349, 0.58461, 0.83202], - [0.48315, 0.57708, 0.82669], - [0.47281, 0.5695, 0.82121], - [0.46249, 0.5619, 0.81559], - [0.4522, 0.55424, 0.80979], - [0.44191, 0.54653, 0.80381], - [0.43166, 0.53878, 0.79763], - [0.42143, 0.53097, 0.79123], - [0.41127, 0.52313, 0.78461], - [0.40119, 0.51523, 0.77775], - [0.39118, 0.5073, 0.77064], - [0.38127, 0.49933, 0.76327], - [0.37146, 0.49137, 0.75565], - [0.36183, 0.48335, 0.74777], - [0.35233, 0.47535, 0.73963], - [0.34304, 0.46735, 0.73123], - [0.33394, 0.45936, 0.72259], - [0.32504, 0.4514, 0.71373], - [0.31641, 0.44349, 0.70464], - [0.30802, 0.43563, 0.69535], - [0.29991, 0.42782, 0.68588], - [0.29207, 0.42009, 0.67624], - [0.28451, 0.41245, 0.66646], - [0.27726, 0.40487, 0.65655], - [0.27029, 0.39741, 0.64654], - [0.26359, 0.39004, 0.63644], - [0.25716, 0.38279, 0.62626], - [0.25101, 0.37562, 0.61604], - [0.24508, 0.36857, 0.60577], - [0.23943, 0.36161, 0.5955], - [0.23398, 0.35476, 0.58521], - [0.22876, 0.34798, 0.57491], - [0.22369, 0.34131, 0.56463], - [0.21881, 0.33473, 0.55436], - [0.21409, 0.3282, 0.54411], - [0.20949, 0.32177, 0.53389], - [0.20502, 0.31541, 0.52371], - [0.20064, 0.30912, 0.51356], - [0.19641, 0.30285, 0.50343], - [0.19221, 0.29668, 0.49335], - [0.18813, 0.29053, 0.48331], - [0.18406, 0.28444, 0.47331], - [0.18006, 0.27841, 0.46335], - [0.17611, 0.27238, 0.45343], - [0.17224, 0.26643, 0.44356], - [0.16839, 0.2605, 0.43371], - [0.16459, 0.25462, 0.42392], - [0.1608, 0.24876, 0.41418], - [0.15705, 0.2429, 0.40446], - [0.15332, 0.23714, 0.3948], - [0.14967, 0.23137, 0.38518], - [0.14601, 0.22564, 0.37561], - [0.14238, 0.21994, 0.36609], - [0.13878, 0.21428, 0.3566], - [0.13523, 0.20865, 0.34717], - [0.13171, 0.20306, 0.33777], - [0.12823, 0.19751, 0.32844], - [0.12476, 0.192, 0.31915], - [0.12134, 0.18655, 0.30992], - [0.11804, 0.18112, 0.30072], - [0.11468, 0.17575, 0.29162], - [0.11149, 0.17047, 0.28256], - [0.10825, 0.16519, 0.27356], - [0.10512, 0.16001, 0.26461], - [0.10208, 0.15492, 0.25575], - [0.099092, 0.14991, 0.24696], - [0.096147, 0.14496, 0.23825], - [0.093305, 0.14005, 0.22961], - [0.090594, 0.13531, 0.22111], - [0.087928, 0.13068, 0.21266], - [0.085292, 0.12614, 0.20436], - [0.082823, 0.12168, 0.19614], - [0.080421, 0.11744, 0.18808], - [0.078086, 0.11339, 0.18011], - [0.075905, 0.10947, 0.17234], - [0.073885, 0.10569, 0.16474], - [0.07186, 0.10213, 0.1573], - [0.069982, 0.098819, 0.15012], - [0.068226, 0.095733, 0.14311], - [0.066537, 0.092861, 0.13632], - [0.064955, 0.090276, 0.12989], - [0.063267, 0.087897, 0.12362], - [0.061329, 0.085713, 0.11774], - [0.059549, 0.084005, 0.11217], - [0.057509, 0.082538, 0.10693], - [0.055684, 0.081475, 0.10197], - [0.05386, 0.080759, 0.097418], - [0.05223, 0.080481, 0.093171], - [0.050913, 0.080625, 0.089271], - [0.049943, 0.081198, 0.085513], - [0.049353, 0.08218, 0.082189], - [0.049079, 0.083464, 0.079009], - [0.049155, 0.085141, 0.076274], - [0.049556, 0.087226, 0.074], - [0.050267, 0.089512, 0.072019], - [0.051322, 0.092107, 0.0705], - [0.052671, 0.094931, 0.069496], - [0.054312, 0.097914, 0.068834], - [0.05624, 0.10103, 0.068579], - [0.058195, 0.10432, 0.068741], - [0.06029, 0.10787, 0.06926], - [0.062176, 0.11172, 0.07], - [0.063928, 0.11578, 0.071095], - [0.065475, 0.12005, 0.072347], - [0.066838, 0.12459, 0.073908], - [0.068268, 0.1293, 0.075503], - [0.069792, 0.13418, 0.077268], - [0.071436, 0.13913, 0.079173], - [0.073206, 0.14428, 0.081195], - [0.075035, 0.14952, 0.083188], - [0.076994, 0.15483, 0.085288], - [0.079073, 0.16025, 0.087584], - [0.081282, 0.16579, 0.089893], - [0.083484, 0.17143, 0.09232], - [0.085728, 0.17716, 0.094882], - [0.088156, 0.18292, 0.097452], - [0.090584, 0.1888, 0.10012], - [0.093019, 0.19475, 0.1029], - [0.095617, 0.2007, 0.10572], - [0.098237, 0.20681, 0.10858], - [0.10086, 0.21289, 0.11157], - [0.1036, 0.21908, 0.11451], - [0.10636, 0.2253, 0.11758], - [0.10914, 0.2316, 0.12066], - [0.11197, 0.23791, 0.1238], - [0.11479, 0.24426, 0.12698], - [0.11773, 0.25069, 0.13025], - [0.12064, 0.25715, 0.13347], - [0.1236, 0.26366, 0.13674], - [0.12662, 0.27019, 0.14004], - [0.12966, 0.27675, 0.14341], - [0.13269, 0.28335, 0.14675], - [0.13572, 0.28998, 0.15017], - [0.13883, 0.29667, 0.15355], - [0.14195, 0.30336, 0.157], - [0.14509, 0.31012, 0.16044], - [0.1482, 0.31687, 0.16397], - [0.15136, 0.32367, 0.16745], - [0.15455, 0.33049, 0.17095], - [0.15775, 0.33736, 0.1745], - [0.16098, 0.34423, 0.17807], - [0.16424, 0.35115, 0.18159], - [0.16749, 0.35809, 0.18522], - [0.17077, 0.36506, 0.18882], - [0.17409, 0.37206, 0.19244], - [0.17746, 0.37909, 0.1961], - [0.18081, 0.38615, 0.19975], - [0.18425, 0.39325, 0.20347], - [0.18776, 0.4004, 0.20721], - [0.19125, 0.40756, 0.21096], - [0.19487, 0.41476, 0.21474], - [0.19852, 0.422, 0.21859], - [0.20228, 0.4293, 0.22246], - [0.20618, 0.43663, 0.22639], - [0.21013, 0.44402, 0.23034], - [0.21425, 0.45145, 0.23439], - [0.21851, 0.45893, 0.23847], - [0.22294, 0.46647, 0.24264], - [0.22756, 0.47407, 0.24689], - [0.23238, 0.48173, 0.25124], - [0.23745, 0.48944, 0.25565], - [0.24273, 0.49723, 0.26018], - [0.24834, 0.50507, 0.26479], - [0.25421, 0.51297, 0.26955], - [0.26039, 0.52093, 0.27439], - [0.26689, 0.52894, 0.27938], - [0.27376, 0.537, 0.28445], - [0.28094, 0.54509, 0.28968], - [0.28851, 0.55322, 0.29502], - [0.29643, 0.56137, 0.30049], - [0.30471, 0.56954, 0.3061], - [0.31334, 0.5777, 0.31178], - [0.32232, 0.58587, 0.31761], - [0.33161, 0.594, 0.32353], - [0.34124, 0.6021, 0.32956], - [0.35116, 0.61015, 0.33565], - [0.36134, 0.61814, 0.34183], - [0.37178, 0.62607, 0.34807], - [0.38245, 0.63392, 0.35437], - [0.39332, 0.64167, 0.3607], - [0.40437, 0.64934, 0.36709], - [0.41558, 0.6569, 0.37349], - [0.42692, 0.66435, 0.37991], - [0.43837, 0.67171, 0.38633], - [0.4499, 0.67896, 0.39277], - [0.46151, 0.68612, 0.39919], - [0.47317, 0.69317, 0.40562], - [0.48488, 0.70011, 0.41201], - [0.49662, 0.70698, 0.41839], - [0.50839, 0.71375, 0.42477], - [0.52015, 0.72044, 0.43112], - [0.53193, 0.72705, 0.43744], - [0.54371, 0.7336, 0.44374], - [0.55548, 0.74009, 0.45002], - [0.56726, 0.74651, 0.45628], - [0.57902, 0.75288, 0.46252], - [0.59077, 0.75922, 0.46875], - [0.60252, 0.76551, 0.47496], - [0.61425, 0.77177, 0.48113], - [0.62598, 0.778, 0.48732], - [0.63771, 0.7842, 0.49347], - [0.64942, 0.79038, 0.49962], - [0.66112, 0.79653, 0.50576], - [0.67283, 0.80268, 0.5119], - [0.68452, 0.80881, 0.51803], - [0.69622, 0.81492, 0.52415], - [0.7079, 0.82103, 0.53026], - [0.71959, 0.82713, 0.53638], - [0.73128, 0.83322, 0.54248], - [0.74297, 0.83931, 0.5486], - [0.75466, 0.84539, 0.5547], - [0.76635, 0.85147, 0.5608], - [0.77804, 0.85754, 0.56691], - [0.78974, 0.86362, 0.57302], - [0.80144, 0.86969, 0.57914], - [0.81315, 0.87576, 0.58525], - [0.82486, 0.88183, 0.59137], - [0.83658, 0.88789, 0.5975], - [0.8483, 0.89396, 0.60363], - [0.86003, 0.90003, 0.60976], -]; - -export const colormap_tokyo_data: Array<[number, number, number]> = [ - [0.10387, 0.056805, 0.20243], - [0.10975, 0.059104, 0.20564], - [0.11566, 0.061046, 0.20884], - [0.1216, 0.063055, 0.21209], - [0.12757, 0.064935, 0.21531], - [0.13351, 0.066895, 0.21858], - [0.13939, 0.068939, 0.22184], - [0.14535, 0.070894, 0.22512], - [0.15119, 0.072938, 0.22845], - [0.15708, 0.07497, 0.23177], - [0.16298, 0.077038, 0.23511], - [0.16886, 0.079188, 0.23844], - [0.17475, 0.081435, 0.24182], - [0.18061, 0.083639, 0.24519], - [0.18652, 0.085843, 0.24863], - [0.19242, 0.088221, 0.25206], - [0.19833, 0.090586, 0.2555], - [0.20429, 0.092949, 0.25898], - [0.21021, 0.095479, 0.26246], - [0.21619, 0.098018, 0.26598], - [0.22212, 0.10056, 0.26951], - [0.22812, 0.10325, 0.27306], - [0.2341, 0.10596, 0.27664], - [0.24009, 0.10871, 0.28021], - [0.2461, 0.11159, 0.28383], - [0.25214, 0.11445, 0.28745], - [0.25815, 0.11746, 0.29112], - [0.26421, 0.12052, 0.29477], - [0.27026, 0.12365, 0.29845], - [0.27631, 0.12687, 0.30215], - [0.28236, 0.13021, 0.30588], - [0.28839, 0.13354, 0.3096], - [0.29442, 0.13697, 0.31333], - [0.30046, 0.14049, 0.31707], - [0.30651, 0.14408, 0.32083], - [0.3125, 0.14775, 0.32457], - [0.3185, 0.15147, 0.32834], - [0.32447, 0.15529, 0.33211], - [0.33042, 0.15918, 0.33586], - [0.33634, 0.16315, 0.33963], - [0.34223, 0.16717, 0.34337], - [0.34808, 0.17124, 0.34711], - [0.35387, 0.1754, 0.35084], - [0.35963, 0.17962, 0.35455], - [0.36533, 0.18389, 0.35824], - [0.37097, 0.18825, 0.36192], - [0.37657, 0.19261, 0.36557], - [0.38208, 0.19706, 0.3692], - [0.38753, 0.2015, 0.37279], - [0.3929, 0.20606, 0.37638], - [0.3982, 0.21059, 0.3799], - [0.40342, 0.21518, 0.3834], - [0.40854, 0.21982, 0.38685], - [0.41357, 0.22443, 0.39027], - [0.41851, 0.22913, 0.39364], - [0.42335, 0.2338, 0.39696], - [0.42811, 0.2385, 0.40025], - [0.43275, 0.24322, 0.40348], - [0.43729, 0.24796, 0.40666], - [0.44172, 0.25267, 0.40979], - [0.44603, 0.25739, 0.41286], - [0.45026, 0.26211, 0.41587], - [0.45436, 0.26682, 0.41882], - [0.45835, 0.27152, 0.42172], - [0.46223, 0.27624, 0.42457], - [0.466, 0.28088, 0.42737], - [0.46968, 0.28555, 0.43009], - [0.47321, 0.29019, 0.43276], - [0.47666, 0.29481, 0.43537], - [0.48, 0.29942, 0.43793], - [0.48321, 0.30398, 0.44041], - [0.48633, 0.30854, 0.44286], - [0.48934, 0.31305, 0.44524], - [0.49226, 0.31754, 0.44756], - [0.49507, 0.322, 0.44984], - [0.49779, 0.32642, 0.45206], - [0.5004, 0.33082, 0.45422], - [0.50292, 0.33521, 0.45633], - [0.50535, 0.33954, 0.45839], - [0.50771, 0.34383, 0.4604], - [0.50996, 0.34812, 0.46237], - [0.51213, 0.35236, 0.46431], - [0.51424, 0.35658, 0.46617], - [0.51624, 0.36075, 0.468], - [0.51819, 0.36491, 0.4698], - [0.52005, 0.36904, 0.47155], - [0.52185, 0.37313, 0.47324], - [0.52359, 0.37721, 0.47493], - [0.52526, 0.38125, 0.47656], - [0.52687, 0.38525, 0.47815], - [0.52841, 0.38925, 0.47973], - [0.5299, 0.39321, 0.48125], - [0.53134, 0.39714, 0.48276], - [0.53273, 0.40107, 0.48423], - [0.53406, 0.40495, 0.48567], - [0.53535, 0.40883, 0.4871], - [0.53661, 0.41269, 0.48849], - [0.53781, 0.41652, 0.48985], - [0.53897, 0.42033, 0.49121], - [0.54009, 0.42412, 0.49252], - [0.54118, 0.42791, 0.49383], - [0.54224, 0.43167, 0.49511], - [0.54326, 0.43542, 0.49637], - [0.54425, 0.43914, 0.49763], - [0.54522, 0.44286, 0.49885], - [0.54616, 0.44657, 0.50006], - [0.54706, 0.45026, 0.50126], - [0.54795, 0.45394, 0.50244], - [0.54882, 0.45761, 0.50361], - [0.54965, 0.46127, 0.50477], - [0.55048, 0.46492, 0.50591], - [0.55128, 0.46856, 0.50705], - [0.55207, 0.4722, 0.50818], - [0.55283, 0.47583, 0.50929], - [0.55358, 0.47945, 0.51039], - [0.55433, 0.48306, 0.51148], - [0.55505, 0.48667, 0.51257], - [0.55576, 0.49027, 0.51365], - [0.55646, 0.49387, 0.51472], - [0.55716, 0.49747, 0.51578], - [0.55783, 0.50106, 0.51684], - [0.5585, 0.50465, 0.5179], - [0.55917, 0.50823, 0.51895], - [0.55983, 0.5118, 0.51997], - [0.56047, 0.51538, 0.52102], - [0.56111, 0.51897, 0.52204], - [0.56175, 0.52253, 0.52308], - [0.56239, 0.52611, 0.5241], - [0.56301, 0.52969, 0.52511], - [0.56363, 0.53325, 0.52613], - [0.56425, 0.53684, 0.52714], - [0.56485, 0.5404, 0.52815], - [0.56546, 0.54398, 0.52916], - [0.56608, 0.54755, 0.53016], - [0.56669, 0.55112, 0.53116], - [0.56729, 0.5547, 0.53216], - [0.56789, 0.55827, 0.53315], - [0.5685, 0.56186, 0.53414], - [0.5691, 0.56543, 0.53513], - [0.5697, 0.56901, 0.53612], - [0.57031, 0.57261, 0.53711], - [0.57092, 0.5762, 0.5381], - [0.57153, 0.57978, 0.53908], - [0.57214, 0.58337, 0.54006], - [0.57276, 0.58696, 0.54104], - [0.57337, 0.59056, 0.54202], - [0.57399, 0.59417, 0.54301], - [0.57461, 0.59778, 0.54399], - [0.57524, 0.60139, 0.54497], - [0.57589, 0.60501, 0.54596], - [0.57653, 0.60864, 0.54694], - [0.57717, 0.61225, 0.54792], - [0.57782, 0.61589, 0.54891], - [0.57849, 0.61954, 0.54989], - [0.57918, 0.62318, 0.55087], - [0.57987, 0.62683, 0.55187], - [0.58056, 0.6305, 0.55286], - [0.58127, 0.63417, 0.55385], - [0.582, 0.63785, 0.55485], - [0.58274, 0.64153, 0.55585], - [0.5835, 0.64523, 0.55687], - [0.58428, 0.64895, 0.55789], - [0.58508, 0.65267, 0.55891], - [0.5859, 0.65641, 0.55995], - [0.58674, 0.66015, 0.56098], - [0.5876, 0.66392, 0.56204], - [0.5885, 0.6677, 0.5631], - [0.58942, 0.67149, 0.56418], - [0.59039, 0.67531, 0.56526], - [0.59139, 0.67914, 0.56637], - [0.59242, 0.683, 0.56749], - [0.59349, 0.68688, 0.56863], - [0.59461, 0.69078, 0.56979], - [0.59578, 0.6947, 0.57097], - [0.597, 0.69866, 0.57219], - [0.59826, 0.70264, 0.57342], - [0.5996, 0.70666, 0.57468], - [0.60099, 0.7107, 0.57599], - [0.60246, 0.71478, 0.57731], - [0.604, 0.7189, 0.57868], - [0.6056, 0.72305, 0.5801], - [0.60731, 0.72725, 0.58155], - [0.60909, 0.73148, 0.58305], - [0.61097, 0.73576, 0.5846], - [0.61294, 0.7401, 0.58621], - [0.61503, 0.74447, 0.58787], - [0.61723, 0.7489, 0.58959], - [0.61955, 0.75338, 0.59139], - [0.62198, 0.75792, 0.59325], - [0.62456, 0.76251, 0.59518], - [0.62727, 0.76716, 0.5972], - [0.63013, 0.77187, 0.5993], - [0.63314, 0.77664, 0.60148], - [0.6363, 0.78146, 0.60376], - [0.63963, 0.78635, 0.60611], - [0.64313, 0.79129, 0.60859], - [0.64681, 0.79629, 0.61116], - [0.65067, 0.80136, 0.61382], - [0.6547, 0.80648, 0.61662], - [0.65894, 0.81164, 0.61951], - [0.66337, 0.81686, 0.62251], - [0.66798, 0.82213, 0.62564], - [0.6728, 0.82743, 0.62888], - [0.6778, 0.83276, 0.63223], - [0.683, 0.83813, 0.6357], - [0.68839, 0.84351, 0.63929], - [0.69397, 0.84891, 0.64299], - [0.69973, 0.85431, 0.64681], - [0.70567, 0.85972, 0.65072], - [0.71178, 0.86509, 0.65474], - [0.71804, 0.87045, 0.65887], - [0.72445, 0.87578, 0.66309], - [0.731, 0.88106, 0.66739], - [0.73768, 0.88628, 0.67178], - [0.74447, 0.89143, 0.67624], - [0.75136, 0.89651, 0.68075], - [0.75833, 0.9015, 0.68534], - [0.76537, 0.90639, 0.68996], - [0.77246, 0.91117, 0.69462], - [0.77959, 0.91583, 0.69932], - [0.78675, 0.92037, 0.70404], - [0.79392, 0.92477, 0.70878], - [0.80108, 0.92904, 0.71351], - [0.80822, 0.93317, 0.71825], - [0.81534, 0.93716, 0.72297], - [0.82241, 0.94098, 0.72768], - [0.82944, 0.94466, 0.73237], - [0.8364, 0.94818, 0.73701], - [0.84329, 0.95154, 0.74163], - [0.8501, 0.95476, 0.74621], - [0.85683, 0.95782, 0.75075], - [0.86348, 0.96072, 0.75524], - [0.87002, 0.96348, 0.75967], - [0.87648, 0.96609, 0.76406], - [0.88284, 0.96857, 0.76839], - [0.8891, 0.9709, 0.77268], - [0.89526, 0.97311, 0.77691], - [0.90133, 0.97518, 0.78108], - [0.90729, 0.97714, 0.7852], - [0.91316, 0.97898, 0.78927], - [0.91894, 0.98071, 0.79329], - [0.92463, 0.98234, 0.79725], - [0.93023, 0.98386, 0.80117], - [0.93575, 0.9853, 0.80504], - [0.94119, 0.98664, 0.80888], - [0.94656, 0.98791, 0.81266], - [0.95185, 0.9891, 0.81642], - [0.95708, 0.99022, 0.82012], - [0.96225, 0.99128, 0.82381], - [0.96736, 0.99228, 0.82746], - [0.97242, 0.99323, 0.83108], - [0.97743, 0.99412, 0.83468], - [0.9824, 0.99498, 0.83825], - [0.98733, 0.99579, 0.84181], - [0.99222, 0.99658, 0.84535], - [0.99708, 0.99733, 0.84887], -]; - -export const colormap_turku_data: Array<[number, number, number]> = [ - [6.3216e-5, 5.1671e-6, 3.583e-5], - [0.0072897, 0.0072041, 0.006548], - [0.01471, 0.014597, 0.013245], - [0.021935, 0.021794, 0.019755], - [0.029159, 0.028991, 0.026252], - [0.03657, 0.036375, 0.032748], - [0.043586, 0.043359, 0.039417], - [0.050168, 0.049959, 0.045556], - [0.056203, 0.055961, 0.051274], - [0.061712, 0.061463, 0.056643], - [0.066992, 0.066746, 0.061506], - [0.071921, 0.071694, 0.066226], - [0.076552, 0.076296, 0.070642], - [0.081056, 0.080777, 0.074828], - [0.085276, 0.085021, 0.078791], - [0.089398, 0.08911, 0.08266], - [0.093274, 0.092973, 0.086288], - [0.09712, 0.096859, 0.089825], - [0.10104, 0.10079, 0.093141], - [0.10494, 0.10467, 0.096482], - [0.10893, 0.10862, 0.099864], - [0.11292, 0.11262, 0.10324], - [0.11686, 0.11656, 0.10659], - [0.12082, 0.1205, 0.10991], - [0.12484, 0.12448, 0.11321], - [0.12884, 0.1285, 0.11649], - [0.13289, 0.13251, 0.11975], - [0.13692, 0.1365, 0.123], - [0.14099, 0.14056, 0.1263], - [0.14505, 0.1446, 0.12953], - [0.14908, 0.14861, 0.13275], - [0.15314, 0.15267, 0.13591], - [0.15722, 0.15676, 0.1391], - [0.16135, 0.16081, 0.14228], - [0.16539, 0.16488, 0.14544], - [0.16953, 0.16899, 0.1485], - [0.17361, 0.17304, 0.15159], - [0.17774, 0.17714, 0.15466], - [0.18181, 0.18121, 0.15769], - [0.18596, 0.18534, 0.1607], - [0.19005, 0.18941, 0.16371], - [0.19419, 0.19352, 0.16664], - [0.19828, 0.19761, 0.16957], - [0.20239, 0.20169, 0.17243], - [0.20655, 0.20582, 0.1753], - [0.21064, 0.2099, 0.17815], - [0.21475, 0.21401, 0.18091], - [0.21887, 0.2181, 0.18368], - [0.22299, 0.22219, 0.18642], - [0.22709, 0.2263, 0.18912], - [0.2312, 0.23036, 0.19178], - [0.23531, 0.23447, 0.19445], - [0.23939, 0.23853, 0.19704], - [0.24347, 0.24261, 0.19958], - [0.24758, 0.24669, 0.20213], - [0.25167, 0.25076, 0.20466], - [0.25574, 0.25485, 0.20713], - [0.25982, 0.2589, 0.20956], - [0.2639, 0.26295, 0.21199], - [0.26794, 0.26699, 0.21436], - [0.272, 0.27106, 0.21672], - [0.27609, 0.2751, 0.21904], - [0.28012, 0.27914, 0.22133], - [0.28416, 0.28317, 0.22359], - [0.28821, 0.28719, 0.22583], - [0.29225, 0.29123, 0.22804], - [0.29629, 0.29524, 0.23019], - [0.30031, 0.29927, 0.23237], - [0.30434, 0.30327, 0.2345], - [0.30837, 0.30728, 0.23661], - [0.31238, 0.3113, 0.23866], - [0.31642, 0.3153, 0.24072], - [0.32044, 0.3193, 0.24276], - [0.32444, 0.3233, 0.24476], - [0.32846, 0.32729, 0.24677], - [0.33249, 0.33128, 0.24876], - [0.33649, 0.3353, 0.2507], - [0.34051, 0.33929, 0.25265], - [0.34452, 0.34327, 0.25458], - [0.34855, 0.34726, 0.25647], - [0.35257, 0.35125, 0.25836], - [0.35661, 0.35525, 0.26025], - [0.36062, 0.35922, 0.26211], - [0.36467, 0.36321, 0.26398], - [0.36872, 0.3672, 0.26582], - [0.37276, 0.3712, 0.26764], - [0.37684, 0.37519, 0.2695], - [0.38091, 0.3792, 0.2713], - [0.38497, 0.38321, 0.27313], - [0.38908, 0.3872, 0.27493], - [0.39318, 0.39122, 0.27675], - [0.3973, 0.39524, 0.27856], - [0.40144, 0.39924, 0.28035], - [0.4056, 0.40328, 0.28218], - [0.40977, 0.4073, 0.28397], - [0.41396, 0.41134, 0.28577], - [0.41817, 0.41538, 0.28759], - [0.42241, 0.41944, 0.28942], - [0.42668, 0.42348, 0.29125], - [0.43097, 0.42756, 0.29307], - [0.4353, 0.43163, 0.29491], - [0.43964, 0.4357, 0.29678], - [0.44402, 0.43979, 0.29864], - [0.44844, 0.44388, 0.30051], - [0.45289, 0.44797, 0.3024], - [0.45737, 0.4521, 0.30432], - [0.4619, 0.45621, 0.30627], - [0.46647, 0.46033, 0.3082], - [0.47109, 0.46448, 0.31018], - [0.47576, 0.46861, 0.31215], - [0.48046, 0.47276, 0.31418], - [0.48521, 0.47692, 0.31623], - [0.49003, 0.48108, 0.31829], - [0.4949, 0.48525, 0.3204], - [0.49981, 0.48942, 0.32252], - [0.5048, 0.49361, 0.32466], - [0.50984, 0.4978, 0.32685], - [0.51494, 0.50198, 0.32909], - [0.5201, 0.50615, 0.33133], - [0.52533, 0.51034, 0.33364], - [0.53062, 0.51453, 0.33596], - [0.53597, 0.5187, 0.33833], - [0.54139, 0.52287, 0.34075], - [0.54688, 0.52703, 0.3432], - [0.55243, 0.53117, 0.34568], - [0.55804, 0.53529, 0.34822], - [0.56373, 0.5394, 0.3508], - [0.56946, 0.54349, 0.3534], - [0.57527, 0.54755, 0.35606], - [0.58113, 0.55159, 0.35875], - [0.58704, 0.55558, 0.36149], - [0.59302, 0.55954, 0.36426], - [0.59904, 0.56346, 0.36708], - [0.6051, 0.56733, 0.36993], - [0.6112, 0.57114, 0.37282], - [0.61734, 0.5749, 0.37575], - [0.62351, 0.5786, 0.37871], - [0.6297, 0.58224, 0.3817], - [0.63592, 0.58581, 0.38472], - [0.64215, 0.58928, 0.38776], - [0.64837, 0.59271, 0.39084], - [0.65461, 0.59602, 0.39392], - [0.66083, 0.59926, 0.39703], - [0.66705, 0.6024, 0.40016], - [0.67324, 0.60545, 0.4033], - [0.6794, 0.60841, 0.40645], - [0.68554, 0.61126, 0.40961], - [0.69163, 0.614, 0.41278], - [0.69767, 0.61665, 0.41594], - [0.70367, 0.61918, 0.41911], - [0.7096, 0.6216, 0.42226], - [0.71548, 0.62393, 0.42543], - [0.72128, 0.62613, 0.42859], - [0.72702, 0.62824, 0.43175], - [0.73268, 0.63023, 0.43489], - [0.73826, 0.63212, 0.43802], - [0.74377, 0.63391, 0.44114], - [0.74919, 0.63559, 0.44426], - [0.75454, 0.63718, 0.44735], - [0.75979, 0.63867, 0.45046], - [0.76496, 0.64007, 0.45354], - [0.77004, 0.64138, 0.45662], - [0.77504, 0.64261, 0.4597], - [0.77996, 0.64375, 0.46277], - [0.7848, 0.64482, 0.46584], - [0.78955, 0.64583, 0.46892], - [0.79423, 0.64677, 0.472], - [0.79883, 0.64765, 0.47508], - [0.80335, 0.64847, 0.47816], - [0.80781, 0.64925, 0.48126], - [0.8122, 0.64999, 0.48437], - [0.81652, 0.65069, 0.48753], - [0.82078, 0.65136, 0.49069], - [0.82499, 0.652, 0.49388], - [0.82914, 0.65263, 0.49711], - [0.83324, 0.65324, 0.50037], - [0.83729, 0.65386, 0.50368], - [0.8413, 0.65448, 0.50704], - [0.84526, 0.6551, 0.51045], - [0.84919, 0.65575, 0.51393], - [0.85308, 0.65642, 0.51746], - [0.85694, 0.65711, 0.52105], - [0.86077, 0.65784, 0.52472], - [0.86458, 0.65861, 0.52847], - [0.86836, 0.65943, 0.5323], - [0.87211, 0.6603, 0.53622], - [0.87584, 0.66124, 0.54022], - [0.87955, 0.66225, 0.54432], - [0.88325, 0.66333, 0.54853], - [0.88692, 0.66449, 0.55281], - [0.89057, 0.66573, 0.55722], - [0.8942, 0.66707, 0.56172], - [0.89781, 0.6685, 0.56633], - [0.90139, 0.67004, 0.57104], - [0.90496, 0.67167, 0.57587], - [0.90849, 0.67342, 0.58079], - [0.912, 0.67527, 0.58583], - [0.91547, 0.67725, 0.59096], - [0.91891, 0.67933, 0.59619], - [0.92231, 0.68154, 0.60153], - [0.92567, 0.68387, 0.60696], - [0.92898, 0.68632, 0.61246], - [0.93224, 0.68889, 0.61806], - [0.93545, 0.69156, 0.62374], - [0.9386, 0.69436, 0.62947], - [0.94168, 0.69728, 0.63527], - [0.9447, 0.70031, 0.64113], - [0.94765, 0.70344, 0.64704], - [0.95052, 0.70669, 0.65298], - [0.95331, 0.71003, 0.65896], - [0.95602, 0.71346, 0.66497], - [0.95865, 0.717, 0.67099], - [0.96119, 0.7206, 0.67702], - [0.96363, 0.7243, 0.68304], - [0.96599, 0.72807, 0.68907], - [0.96826, 0.73191, 0.69507], - [0.97043, 0.73581, 0.70105], - [0.97251, 0.73978, 0.70702], - [0.97448, 0.74378, 0.71294], - [0.97637, 0.74785, 0.71883], - [0.97816, 0.75195, 0.72468], - [0.97987, 0.75608, 0.73048], - [0.98148, 0.76025, 0.73623], - [0.983, 0.76445, 0.74194], - [0.98444, 0.76867, 0.74759], - [0.98578, 0.77292, 0.75318], - [0.98705, 0.77719, 0.75873], - [0.98823, 0.78146, 0.76421], - [0.98935, 0.78575, 0.76963], - [0.99038, 0.79004, 0.775], - [0.99134, 0.79435, 0.78032], - [0.99224, 0.79865, 0.78558], - [0.99307, 0.80296, 0.79078], - [0.99383, 0.80727, 0.79594], - [0.99453, 0.81158, 0.80104], - [0.99518, 0.8159, 0.8061], - [0.99577, 0.8202, 0.81111], - [0.99632, 0.82451, 0.81608], - [0.99681, 0.82882, 0.821], - [0.99726, 0.83312, 0.82588], - [0.99767, 0.83743, 0.83074], - [0.99804, 0.84173, 0.83555], - [0.99837, 0.84602, 0.84033], - [0.99866, 0.85032, 0.84508], - [0.99892, 0.85461, 0.84981], - [0.99915, 0.8589, 0.85451], - [0.99934, 0.86319, 0.85919], - [0.99951, 0.86747, 0.86385], - [0.99965, 0.87176, 0.86849], - [0.99977, 0.87604, 0.87312], - [0.99986, 0.88032, 0.87773], - [0.99994, 0.88461, 0.88233], - [0.99999, 0.88889, 0.88693], - [1, 0.89317, 0.89151], - [1, 0.89746, 0.89609], - [1, 0.90174, 0.90067], -]; - -export const colormap_vik_data: Array<[number, number, number]> = [ - [0.0013282, 0.069836, 0.37953], - [0.0023664, 0.076475, 0.38352], - [0.0033042, 0.083083, 0.38749], - [0.0041459, 0.08959, 0.39148], - [0.0048968, 0.095948, 0.39545], - [0.0055632, 0.10227, 0.39941], - [0.0061512, 0.1085, 0.40339], - [0.0066676, 0.11469, 0.40734], - [0.0071192, 0.12085, 0.41129], - [0.0075116, 0.12696, 0.41523], - [0.0078503, 0.13307, 0.41917], - [0.0081413, 0.13909, 0.42308], - [0.0083912, 0.14517, 0.42701], - [0.0086057, 0.15114, 0.43091], - [0.0087895, 0.15714, 0.43481], - [0.0089466, 0.16315, 0.43869], - [0.0090802, 0.16914, 0.44259], - [0.0091935, 0.1751, 0.44646], - [0.0092897, 0.18105, 0.45034], - [0.0093719, 0.18705, 0.45421], - [0.0094431, 0.19303, 0.45808], - [0.0095061, 0.199, 0.46195], - [0.0095639, 0.20501, 0.46582], - [0.0096192, 0.21102, 0.46971], - [0.0096751, 0.21705, 0.47357], - [0.0097347, 0.22308, 0.47746], - [0.0098019, 0.22912, 0.48135], - [0.0098809, 0.23521, 0.48525], - [0.0099771, 0.24128, 0.48916], - [0.010098, 0.24739, 0.49308], - [0.010254, 0.25352, 0.49702], - [0.010463, 0.25968, 0.50097], - [0.010755, 0.26585, 0.50494], - [0.011176, 0.27204, 0.50893], - [0.011716, 0.2783, 0.51292], - [0.012286, 0.28455, 0.51695], - [0.012934, 0.29087, 0.521], - [0.01379, 0.29721, 0.52507], - [0.014838, 0.30358, 0.52918], - [0.016131, 0.31002, 0.53331], - [0.017711, 0.31647, 0.53748], - [0.01963, 0.32299, 0.54168], - [0.021948, 0.32955, 0.54593], - [0.02473, 0.33614, 0.55021], - [0.028047, 0.34283, 0.55454], - [0.03198, 0.34954, 0.55891], - [0.036812, 0.35633, 0.56334], - [0.042229, 0.36317, 0.56781], - [0.048008, 0.37009, 0.57235], - [0.054292, 0.37708, 0.57693], - [0.060963, 0.38413, 0.58157], - [0.068081, 0.39126, 0.58628], - [0.075457, 0.39846, 0.59104], - [0.083246, 0.40574, 0.59587], - [0.091425, 0.41309, 0.60075], - [0.099832, 0.4205, 0.6057], - [0.10859, 0.428, 0.61071], - [0.11769, 0.43557, 0.61577], - [0.12704, 0.44319, 0.6209], - [0.1367, 0.45089, 0.62606], - [0.14661, 0.45864, 0.63129], - [0.15679, 0.46646, 0.63656], - [0.16719, 0.47432, 0.64187], - [0.17781, 0.48224, 0.64722], - [0.18861, 0.49019, 0.6526], - [0.19958, 0.49819, 0.65802], - [0.21078, 0.5062, 0.66346], - [0.22212, 0.51426, 0.66892], - [0.2336, 0.52232, 0.6744], - [0.24523, 0.53041, 0.67989], - [0.257, 0.53852, 0.68541], - [0.26887, 0.54662, 0.69091], - [0.2808, 0.55472, 0.69643], - [0.29285, 0.56282, 0.70193], - [0.30498, 0.57091, 0.70745], - [0.31717, 0.579, 0.71295], - [0.32944, 0.58706, 0.71845], - [0.34173, 0.59512, 0.72393], - [0.35407, 0.60316, 0.72941], - [0.36646, 0.61119, 0.73488], - [0.37886, 0.61919, 0.74032], - [0.39131, 0.62716, 0.74576], - [0.40376, 0.63511, 0.75118], - [0.41623, 0.64305, 0.75658], - [0.42871, 0.65096, 0.76197], - [0.4412, 0.65884, 0.76734], - [0.4537, 0.6667, 0.7727], - [0.4662, 0.67454, 0.77804], - [0.4787, 0.68235, 0.78337], - [0.49121, 0.69014, 0.78868], - [0.50369, 0.69791, 0.79398], - [0.51618, 0.70566, 0.79926], - [0.52868, 0.71339, 0.80452], - [0.54115, 0.72109, 0.80977], - [0.55362, 0.72878, 0.81501], - [0.5661, 0.73644, 0.82023], - [0.57856, 0.74409, 0.82544], - [0.59101, 0.75172, 0.83063], - [0.60347, 0.75931, 0.83579], - [0.61591, 0.7669, 0.84094], - [0.62835, 0.77445, 0.84606], - [0.64078, 0.78199, 0.85115], - [0.6532, 0.78949, 0.85621], - [0.66563, 0.79694, 0.86121], - [0.67805, 0.80437, 0.86617], - [0.69046, 0.81174, 0.87106], - [0.70287, 0.81905, 0.87587], - [0.71526, 0.82629, 0.88057], - [0.72765, 0.83344, 0.88515], - [0.74002, 0.84048, 0.88957], - [0.75235, 0.84738, 0.89381], - [0.76466, 0.85413, 0.89782], - [0.77692, 0.86068, 0.90156], - [0.7891, 0.86699, 0.90499], - [0.80117, 0.87303, 0.90804], - [0.81311, 0.87874, 0.91065], - [0.82487, 0.88406, 0.91276], - [0.8364, 0.88893, 0.9143], - [0.84762, 0.89329, 0.9152], - [0.85847, 0.89707, 0.91539], - [0.86887, 0.90021, 0.91481], - [0.87873, 0.90264, 0.91342], - [0.88797, 0.9043, 0.91116], - [0.8965, 0.90518, 0.90803], - [0.90424, 0.90522, 0.90401], - [0.91115, 0.90442, 0.89913], - [0.91718, 0.9028, 0.89341], - [0.92229, 0.90037, 0.88691], - [0.92648, 0.89717, 0.87969], - [0.92979, 0.89326, 0.87183], - [0.93224, 0.8887, 0.8634], - [0.93388, 0.88355, 0.85448], - [0.93478, 0.87789, 0.84515], - [0.93501, 0.8718, 0.83549], - [0.93464, 0.86531, 0.82556], - [0.93375, 0.85852, 0.81542], - [0.93241, 0.85147, 0.80511], - [0.93068, 0.84421, 0.79468], - [0.92862, 0.83678, 0.78417], - [0.9263, 0.82921, 0.77358], - [0.92375, 0.82154, 0.76296], - [0.92102, 0.8138, 0.75231], - [0.91815, 0.806, 0.74166], - [0.91516, 0.79816, 0.73101], - [0.91208, 0.79029, 0.72037], - [0.90893, 0.78242, 0.70975], - [0.90574, 0.77454, 0.69915], - [0.90251, 0.76667, 0.68859], - [0.89925, 0.75881, 0.67805], - [0.89597, 0.75097, 0.66755], - [0.89269, 0.74315, 0.65709], - [0.8894, 0.73535, 0.64666], - [0.88612, 0.72757, 0.63627], - [0.88283, 0.71983, 0.62592], - [0.87956, 0.71211, 0.61562], - [0.87629, 0.70442, 0.60536], - [0.87303, 0.69676, 0.59514], - [0.86978, 0.68914, 0.58497], - [0.86655, 0.68154, 0.57483], - [0.86333, 0.67398, 0.56475], - [0.86012, 0.66645, 0.55471], - [0.85692, 0.65896, 0.54471], - [0.85373, 0.6515, 0.53475], - [0.85056, 0.64406, 0.52484], - [0.8474, 0.63667, 0.51497], - [0.84426, 0.6293, 0.50515], - [0.84113, 0.62196, 0.49537], - [0.838, 0.61465, 0.48563], - [0.83489, 0.60739, 0.47594], - [0.8318, 0.60014, 0.46628], - [0.82872, 0.59294, 0.45668], - [0.82564, 0.58576, 0.44711], - [0.82258, 0.5786, 0.43759], - [0.81953, 0.57148, 0.42811], - [0.8165, 0.56439, 0.41866], - [0.81346, 0.55733, 0.40926], - [0.81045, 0.55028, 0.39989], - [0.80744, 0.54327, 0.39058], - [0.80445, 0.53629, 0.3813], - [0.80145, 0.52933, 0.37204], - [0.79847, 0.52238, 0.36284], - [0.7955, 0.51546, 0.35366], - [0.79253, 0.50857, 0.34452], - [0.78957, 0.50169, 0.33544], - [0.78662, 0.49483, 0.32634], - [0.78366, 0.48798, 0.31731], - [0.7807, 0.48112, 0.3083], - [0.77774, 0.4743, 0.29933], - [0.77476, 0.46746, 0.29035], - [0.77179, 0.46062, 0.28142], - [0.76879, 0.45378, 0.27251], - [0.76578, 0.44693, 0.26364], - [0.76272, 0.44005, 0.25476], - [0.75964, 0.43315, 0.24587], - [0.75651, 0.4262, 0.23705], - [0.75332, 0.41922, 0.22819], - [0.75005, 0.41216, 0.21933], - [0.7467, 0.40503, 0.21047], - [0.74324, 0.39782, 0.20159], - [0.73965, 0.39049, 0.19274], - [0.7359, 0.38306, 0.18385], - [0.73199, 0.37547, 0.17498], - [0.72786, 0.36774, 0.16605], - [0.72352, 0.35985, 0.15713], - [0.71891, 0.35177, 0.14821], - [0.71403, 0.3435, 0.13928], - [0.70884, 0.33505, 0.13046], - [0.70332, 0.32635, 0.12154], - [0.69745, 0.3175, 0.11284], - [0.69123, 0.30846, 0.10413], - [0.68465, 0.29926, 0.095633], - [0.67773, 0.28992, 0.08735], - [0.67048, 0.28048, 0.079197], - [0.6629, 0.27102, 0.07151], - [0.65505, 0.26152, 0.064079], - [0.64697, 0.25208, 0.057104], - [0.63869, 0.24271, 0.050618], - [0.63026, 0.23349, 0.04475], - [0.62172, 0.22445, 0.039414], - [0.61313, 0.21566, 0.034829], - [0.60454, 0.20709, 0.031072], - [0.59595, 0.19874, 0.028212], - [0.5874, 0.1907, 0.026019], - [0.57894, 0.18292, 0.024396], - [0.57054, 0.17542, 0.023257], - [0.56227, 0.16817, 0.022523], - [0.55408, 0.1612, 0.02211], - [0.54601, 0.1544, 0.021861], - [0.53804, 0.14785, 0.021737], - [0.53018, 0.14149, 0.021722], - [0.52242, 0.13528, 0.0218], - [0.51478, 0.12921, 0.021957], - [0.50721, 0.12327, 0.022179], - [0.49973, 0.11749, 0.022455], - [0.49235, 0.11182, 0.022775], - [0.48503, 0.10621, 0.02313], - [0.4778, 0.10061, 0.023513], - [0.47064, 0.095156, 0.023916], - [0.46353, 0.089668, 0.024336], - [0.45649, 0.084258, 0.024766], - [0.44952, 0.078741, 0.025203], - [0.4426, 0.073404, 0.025644], - [0.43574, 0.067904, 0.026084], - [0.42892, 0.062415, 0.026522], - [0.42215, 0.056832, 0.026954], - [0.41544, 0.051116, 0.027378], - [0.40877, 0.045352, 0.02779], - [0.40213, 0.039448, 0.028189], - [0.39556, 0.033385, 0.02857], - [0.38902, 0.027844, 0.028932], - [0.3825, 0.022586, 0.029271], - [0.37603, 0.017608, 0.029583], - [0.36958, 0.01289, 0.029866], - [0.36316, 0.0082428, 0.030115], - [0.35679, 0.0040345, 0.030327], - [0.35042, 6.1141e-5, 0.030499], -]; - -export const colormap_viko_data: Array<[number, number, number]> = [ - [0.30979, 0.1009, 0.23843], - [0.30692, 0.10306, 0.24318], - [0.30406, 0.10526, 0.24805], - [0.30121, 0.10764, 0.25296], - [0.29836, 0.11017, 0.25796], - [0.29551, 0.11276, 0.26307], - [0.29265, 0.11545, 0.26825], - [0.2898, 0.11832, 0.27354], - [0.28692, 0.12122, 0.27891], - [0.28406, 0.12431, 0.28434], - [0.28118, 0.12753, 0.28989], - [0.2783, 0.13089, 0.29552], - [0.27542, 0.13435, 0.30123], - [0.27249, 0.13793, 0.30704], - [0.2696, 0.14163, 0.31293], - [0.26666, 0.14548, 0.3189], - [0.26374, 0.14942, 0.32495], - [0.26079, 0.15348, 0.33107], - [0.25783, 0.15771, 0.33729], - [0.25491, 0.16208, 0.34356], - [0.25194, 0.16655, 0.34991], - [0.24899, 0.17114, 0.35633], - [0.24602, 0.17586, 0.36279], - [0.24308, 0.18073, 0.36931], - [0.24015, 0.18575, 0.37589], - [0.23728, 0.19084, 0.38251], - [0.23439, 0.19609, 0.38918], - [0.23155, 0.20143, 0.39588], - [0.22875, 0.20694, 0.40259], - [0.226, 0.21253, 0.40935], - [0.22331, 0.21825, 0.41612], - [0.22071, 0.22406, 0.42289], - [0.21817, 0.23, 0.42969], - [0.21576, 0.23608, 0.43648], - [0.21343, 0.24222, 0.44326], - [0.21128, 0.24849, 0.45004], - [0.20925, 0.25484, 0.4568], - [0.20741, 0.26127, 0.46354], - [0.20574, 0.26779, 0.47026], - [0.20429, 0.27443, 0.47695], - [0.20303, 0.28113, 0.48361], - [0.20203, 0.28792, 0.49024], - [0.20129, 0.29478, 0.49683], - [0.20083, 0.30171, 0.50338], - [0.20067, 0.30874, 0.50989], - [0.20082, 0.31581, 0.51636], - [0.2013, 0.32294, 0.52278], - [0.20213, 0.33012, 0.52917], - [0.20331, 0.33737, 0.53549], - [0.20484, 0.34466, 0.54177], - [0.20676, 0.35201, 0.54801], - [0.209, 0.35941, 0.5542], - [0.21166, 0.36686, 0.56035], - [0.21466, 0.37435, 0.56644], - [0.21806, 0.38186, 0.57249], - [0.22181, 0.38942, 0.57849], - [0.22595, 0.39701, 0.58446], - [0.2304, 0.40464, 0.59037], - [0.23526, 0.41231, 0.59625], - [0.24039, 0.41999, 0.60208], - [0.24588, 0.42771, 0.60787], - [0.25172, 0.43544, 0.61361], - [0.25782, 0.44319, 0.61933], - [0.26424, 0.45096, 0.62499], - [0.27094, 0.45875, 0.63062], - [0.27791, 0.46655, 0.6362], - [0.28513, 0.47436, 0.64173], - [0.29262, 0.48218, 0.64724], - [0.30034, 0.48999, 0.65269], - [0.30829, 0.49783, 0.65811], - [0.31647, 0.50564, 0.66348], - [0.32484, 0.51347, 0.66879], - [0.33343, 0.52127, 0.67406], - [0.3422, 0.52908, 0.67927], - [0.35115, 0.53686, 0.68443], - [0.36026, 0.54462, 0.68955], - [0.36956, 0.55236, 0.69458], - [0.37901, 0.56007, 0.69956], - [0.38861, 0.56775, 0.70447], - [0.39834, 0.57539, 0.70931], - [0.40821, 0.58298, 0.71406], - [0.4182, 0.59053, 0.71873], - [0.42832, 0.59803, 0.72331], - [0.43853, 0.60546, 0.7278], - [0.44887, 0.61283, 0.73218], - [0.45928, 0.62014, 0.73644], - [0.46979, 0.62734, 0.7406], - [0.48036, 0.63448, 0.74462], - [0.49102, 0.6415, 0.74851], - [0.50172, 0.64843, 0.75226], - [0.51247, 0.65525, 0.75586], - [0.52327, 0.66195, 0.75929], - [0.53409, 0.66852, 0.76256], - [0.54494, 0.67495, 0.76565], - [0.55578, 0.68123, 0.76854], - [0.56664, 0.68736, 0.77124], - [0.57747, 0.69332, 0.77372], - [0.58828, 0.6991, 0.77598], - [0.59905, 0.7047, 0.77802], - [0.60976, 0.7101, 0.77981], - [0.62041, 0.71529, 0.78135], - [0.63096, 0.72026, 0.78263], - [0.64142, 0.72501, 0.78364], - [0.65177, 0.72951, 0.78438], - [0.662, 0.73377, 0.78482], - [0.67207, 0.73776, 0.78496], - [0.68198, 0.74149, 0.78481], - [0.69173, 0.74495, 0.78434], - [0.70129, 0.74812, 0.78356], - [0.71064, 0.751, 0.78246], - [0.71977, 0.75357, 0.78103], - [0.72866, 0.75584, 0.77928], - [0.7373, 0.75781, 0.7772], - [0.74568, 0.75945, 0.77478], - [0.75379, 0.76078, 0.77204], - [0.76161, 0.76178, 0.76897], - [0.76913, 0.76246, 0.76558], - [0.77635, 0.76282, 0.76186], - [0.78325, 0.76286, 0.75783], - [0.78982, 0.76257, 0.75349], - [0.79607, 0.76197, 0.74884], - [0.80198, 0.76105, 0.7439], - [0.80756, 0.75982, 0.73867], - [0.81279, 0.75829, 0.73316], - [0.81768, 0.75645, 0.72738], - [0.82224, 0.75433, 0.72135], - [0.82645, 0.75191, 0.71507], - [0.83032, 0.74922, 0.70856], - [0.83386, 0.74627, 0.70181], - [0.83707, 0.74306, 0.69486], - [0.83996, 0.7396, 0.68771], - [0.84252, 0.73588, 0.68036], - [0.84477, 0.73195, 0.67285], - [0.84672, 0.72779, 0.66516], - [0.84838, 0.72343, 0.65733], - [0.84974, 0.71887, 0.64934], - [0.85082, 0.71411, 0.64122], - [0.85164, 0.70918, 0.63299], - [0.8522, 0.70406, 0.62464], - [0.8525, 0.69879, 0.61619], - [0.85256, 0.69337, 0.60765], - [0.85238, 0.68779, 0.59901], - [0.85198, 0.68208, 0.5903], - [0.85135, 0.67624, 0.58153], - [0.85052, 0.67028, 0.5727], - [0.8495, 0.66419, 0.56381], - [0.84827, 0.65799, 0.55487], - [0.84686, 0.65169, 0.54589], - [0.84527, 0.64528, 0.53688], - [0.8435, 0.63879, 0.52782], - [0.84157, 0.6322, 0.51875], - [0.83948, 0.62552, 0.50965], - [0.83723, 0.61876, 0.50053], - [0.83482, 0.61191, 0.49142], - [0.83226, 0.60499, 0.48228], - [0.82956, 0.59798, 0.47312], - [0.82672, 0.59091, 0.46399], - [0.82372, 0.58376, 0.45485], - [0.8206, 0.57655, 0.4457], - [0.81733, 0.56924, 0.43657], - [0.81392, 0.56189, 0.42746], - [0.81038, 0.55445, 0.41834], - [0.80671, 0.54695, 0.40925], - [0.80289, 0.53937, 0.40018], - [0.79894, 0.53172, 0.39114], - [0.79485, 0.52401, 0.38211], - [0.79062, 0.51622, 0.37312], - [0.78625, 0.50837, 0.36416], - [0.78173, 0.50043, 0.35526], - [0.77707, 0.49243, 0.34637], - [0.77227, 0.48436, 0.33755], - [0.76731, 0.47623, 0.32878], - [0.76221, 0.46802, 0.32008], - [0.75697, 0.45974, 0.31141], - [0.75157, 0.4514, 0.30283], - [0.74602, 0.443, 0.29434], - [0.74032, 0.43452, 0.28593], - [0.73447, 0.42599, 0.27763], - [0.72846, 0.41741, 0.26943], - [0.72231, 0.40876, 0.26133], - [0.71602, 0.40008, 0.25336], - [0.70958, 0.39136, 0.24551], - [0.703, 0.38259, 0.23784], - [0.69628, 0.37381, 0.23028], - [0.68944, 0.36499, 0.22293], - [0.68246, 0.35617, 0.21574], - [0.67538, 0.34735, 0.20873], - [0.66819, 0.33852, 0.20192], - [0.66089, 0.32973, 0.19535], - [0.6535, 0.32095, 0.189], - [0.64604, 0.31219, 0.18286], - [0.6385, 0.30351, 0.177], - [0.63092, 0.29488, 0.17138], - [0.62328, 0.28632, 0.16602], - [0.6156, 0.27787, 0.16097], - [0.60792, 0.2695, 0.15619], - [0.60022, 0.26122, 0.15165], - [0.59253, 0.25308, 0.14746], - [0.58486, 0.24505, 0.14353], - [0.57721, 0.23721, 0.13988], - [0.56961, 0.22946, 0.13656], - [0.56209, 0.2219, 0.13356], - [0.55461, 0.21451, 0.13084], - [0.54721, 0.20731, 0.12838], - [0.5399, 0.20025, 0.12623], - [0.5327, 0.19344, 0.12431], - [0.5256, 0.18679, 0.12269], - [0.51862, 0.18034, 0.12135], - [0.51174, 0.17413, 0.12028], - [0.505, 0.16809, 0.11946], - [0.49839, 0.16231, 0.11889], - [0.49191, 0.15672, 0.11853], - [0.48556, 0.15132, 0.11838], - [0.47937, 0.14618, 0.11844], - [0.47329, 0.14126, 0.1187], - [0.46739, 0.1365, 0.11913], - [0.46161, 0.13203, 0.11974], - [0.45597, 0.12774, 0.12054], - [0.45047, 0.12364, 0.1215], - [0.44511, 0.1198, 0.12263], - [0.43989, 0.1162, 0.12393], - [0.43479, 0.11277, 0.12538], - [0.42983, 0.10956, 0.12692], - [0.425, 0.10654, 0.12863], - [0.42027, 0.10371, 0.13049], - [0.41568, 0.10106, 0.13241], - [0.4112, 0.098655, 0.13449], - [0.40683, 0.096378, 0.13662], - [0.40256, 0.09442, 0.1389], - [0.3984, 0.092523, 0.14132], - [0.39433, 0.090892, 0.14379], - [0.39036, 0.089396, 0.14636], - [0.38647, 0.08809, 0.14904], - [0.38268, 0.086971, 0.1518], - [0.37896, 0.085915, 0.15466], - [0.37531, 0.085142, 0.15761], - [0.37174, 0.084549, 0.16064], - [0.36825, 0.08407, 0.1638], - [0.3648, 0.083717, 0.167], - [0.36142, 0.083521, 0.17027], - [0.3581, 0.083485, 0.17363], - [0.35484, 0.083605, 0.17709], - [0.3516, 0.083878, 0.1806], - [0.34843, 0.084281, 0.18422], - [0.34529, 0.084781, 0.18793], - [0.34219, 0.085387, 0.19167], - [0.33913, 0.086179, 0.19552], - [0.33609, 0.087176, 0.19943], - [0.3331, 0.08819, 0.20346], - [0.33012, 0.089356, 0.20755], - [0.32715, 0.090652, 0.21172], - [0.32422, 0.092078, 0.21597], - [0.32131, 0.093564, 0.22031], - [0.31841, 0.095269, 0.22468], - [0.31553, 0.096976, 0.2292], - [0.31264, 0.098899, 0.23377], -]; diff --git a/projects/wave-core/src/lib/config.service.ts b/projects/wave-core/src/lib/config.service.ts deleted file mode 100644 index d53335b7..00000000 --- a/projects/wave-core/src/lib/config.service.ts +++ /dev/null @@ -1,211 +0,0 @@ -import {of} from 'rxjs'; -import {catchError, tap} from 'rxjs/operators'; -import {Injectable} from '@angular/core'; -import {mergeDeep} from 'immutable'; -import {HttpClient} from '@angular/common/http'; - -type MappingUrlType = string; - -interface Wms { - readonly VERSION: string; - readonly FORMAT: string; -} - -interface Wfs { - readonly VERSION: string; - readonly FORMAT: string; -} - -interface Wcs { - readonly SERVICE: string; - readonly VERSION: string; -} - -interface DebugMode { - readonly WAVE: boolean; - readonly MAPPING: boolean; -} - -interface User { - readonly GUEST: { - readonly NAME: string; - readonly PASSWORD: string; - }; -} - -interface Delays { - readonly LOADING: { - readonly MIN: number; - }; - readonly TOOLTIP: number; - readonly DEBOUNCE: number; - readonly STORAGE_DEBOUNCE: number; - readonly GUEST_LOGIN_HINT: number; -} - -interface Defaults { - readonly PROJECT: { - readonly NAME: string; - readonly TIME: string; - readonly TIMESTEP: '15 minutes' | '1 hour' | '1 day' | '1 month' | '6 months' | '1 year'; - readonly PROJECTION: 'EPSG:3857' | 'EPSG:4326'; - }; -} - -interface Map { - readonly BACKGROUND_LAYER: 'OSM' | 'countries' | 'hosted' | 'XYZ'; - readonly BACKGROUND_LAYER_URL: string; - readonly HOSTED_BACKGROUND_SERVICE: string; - readonly HOSTED_BACKGROUND_LAYER_NAME: string; - readonly HOSTED_BACKGROUND_SERVICE_VERSION: string; - readonly REFRESH_LAYERS_ON_CHANGE: boolean; -} - -interface Time { - readonly ALLOW_RANGES: boolean; -} - -export interface WaveConfigStructure { - readonly DEBUG_MODE: DebugMode; - readonly DEFAULTS: Defaults; - readonly DELAYS: Delays; - readonly MAP: Map; - readonly MAPPING_URL: MappingUrlType; - readonly TIME: Time; - readonly USER: User; - readonly WCS: Wcs; - readonly WFS: Wfs; - readonly WMS: Wms; -} - -export const WAVE_DEFAULT_CONFIG: WaveConfigStructure = { - DEBUG_MODE: { - WAVE: false, - MAPPING: false, - }, - DEFAULTS: { - PROJECT: { - NAME: 'Default', - TIME: '2000-06-06T12:00:00.000Z', - TIMESTEP: '1 month', - PROJECTION: 'EPSG:3857', - }, - }, - DELAYS: { - LOADING: { - MIN: 500, - }, - TOOLTIP: 400, - DEBOUNCE: 400, - STORAGE_DEBOUNCE: 1500, - GUEST_LOGIN_HINT: 5000, - }, - MAP: { - BACKGROUND_LAYER: 'OSM', - BACKGROUND_LAYER_URL: '', - HOSTED_BACKGROUND_SERVICE: '/mapcache/', - HOSTED_BACKGROUND_LAYER_NAME: 'osm', - HOSTED_BACKGROUND_SERVICE_VERSION: '1.1.1', - REFRESH_LAYERS_ON_CHANGE: false, - }, - MAPPING_URL: '/cgi-bin/mapping_cgi', - TIME: { - ALLOW_RANGES: true, - }, - USER: { - GUEST: { - NAME: 'guest', - PASSWORD: 'guest', - }, - }, - WCS: { - SERVICE: 'WCS', - VERSION: '2.0.1', - }, - WFS: { - VERSION: '2.0.0', - FORMAT: 'application/json', - }, - WMS: { - VERSION: '1.3.0', - FORMAT: 'image/png', - }, -}; - -/** - * A service that provides config entries. - * Loads a custom file at startup. - */ -@Injectable() -export class Config { - static readonly CONFIG_FILE = 'assets/config.json'; - - protected config: WaveConfigStructure; - - get MAPPING_URL(): MappingUrlType { - return this.config.MAPPING_URL; - } - - get WMS(): Wms { - return this.config.WMS; - } - - get WFS(): Wfs { - return this.config.WFS; - } - - get WCS(): Wcs { - return this.config.WCS; - } - - get DEBUG_MODE(): DebugMode { - return this.config.DEBUG_MODE; - } - - get USER(): User { - return this.config.USER; - } - - get DELAYS(): Delays { - return this.config.DELAYS; - } - - get DEFAULTS(): Defaults { - return this.config.DEFAULTS; - } - - get MAP(): Map { - return this.config.MAP; - } - - get TIME(): Time { - return this.config.TIME; - } - - constructor(protected http: HttpClient) {} - - // noinspection JSUnusedGlobalSymbols <- function used in parent app - /** - * Initialize the config on app start. - */ - load(defaults?: WaveConfigStructure): Promise { - if (!defaults) { - defaults = WAVE_DEFAULT_CONFIG; - } - return this.http - .get(Config.CONFIG_FILE) - .pipe( - tap( - (appConfig) => { - this.config = mergeDeep(defaults, appConfig); - }, - () => { - // error - this.config = defaults; - }, - ), - catchError(() => of(undefined)), - ) - .toPromise(); - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/audio/mediaview.audio.component.html b/projects/wave-core/src/lib/datatable/mediaview/audio/mediaview.audio.component.html deleted file mode 100644 index f2ec0806..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/audio/mediaview.audio.component.html +++ /dev/null @@ -1,17 +0,0 @@ -Audio {{ currentAudio + 1 }} of {{ audioURLs.length }} - -
- - - - -
-

{{ audioURLs[currentAudio] | fileName }}

- - - open_in_new - -
- - -
diff --git a/projects/wave-core/src/lib/datatable/mediaview/audio/mediaview.audio.component.scss b/projects/wave-core/src/lib/datatable/mediaview/audio/mediaview.audio.component.scss deleted file mode 100644 index aaca3cf6..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/audio/mediaview.audio.component.scss +++ /dev/null @@ -1,34 +0,0 @@ -$mat-icon-button-size: 40px !default; // TODO: import when this is possible again - -.audioContainer { - mat-card { - width: calc(100% - 2rem); - margin: 1rem; - padding: 0; - } - - audio { - width: 100%; - margin: 0; - display: block; - } - - .info { - float: left; - width: 100%; - - h3 { - float: left; - margin: 1rem; - width: calc(100% - 4rem - #{$mat-icon-button-size}); - overflow: hidden; - text-overflow: ellipsis; - word-break: keep-all; - } - - .externalLink { - float: right; - margin: 1rem; - } - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/audio/mediaview.audio.component.ts b/projects/wave-core/src/lib/datatable/mediaview/audio/mediaview.audio.component.ts deleted file mode 100644 index f159ba6f..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/audio/mediaview.audio.component.ts +++ /dev/null @@ -1,48 +0,0 @@ -import {Component, Input} from '@angular/core'; -import {SidenavHeaderComponent} from '../../../sidenav/sidenav-header/sidenav-header.component'; - -@Component({ - selector: 'wave-mediaview-audio', - templateUrl: './mediaview.audio.component.html', - styleUrls: ['./mediaview.audio.component.scss'], -}) - -/** - * Dialog-Audio-Component - * Is shown as a dialog-popup. - * Displays an audio-player with a playlist. - * The component receives an array of urls to audio-files (audioURLS) and the id of the audio to play first (currentAudio) as inputs. - */ -export class MediaviewAudioComponent { - /** - * Input: An array of audio-urls to display in the dialog - */ - @Input() - public audioURLs: string[]; - - /** - * Input: The index of the audio-file to play first - */ - @Input() - public currentAudio: number; - - public autoPlay: boolean; - - /** - * Plays the audio with given id, skipping the currently playing one - * @param audioID the ID auf the audio-file to play - */ - public goToAudio(audioID: number) { - this.currentAudio = audioID; - this.autoPlay = true; - } - - /** - * Plays the next audio in the list of audio-urls - * If the current file is the last one, plays the first one - * Is called when the current audio has finished playing - */ - public playNext() { - this.goToAudio((this.currentAudio + 1) % this.audioURLs.length); - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/filename.pipe.ts b/projects/wave-core/src/lib/datatable/mediaview/filename.pipe.ts deleted file mode 100644 index 253992f7..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/filename.pipe.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Pipe, PipeTransform} from '@angular/core'; - -@Pipe({ - name: 'fileName', -}) -/** - * FileNamePipe - * Transforms a given string with a file-url to only the filename - */ -export class FileNamePipe implements PipeTransform { - /** - * Transforms a given string with a file-url to only the file-name - * @param value url directing to a file - * @returns {string} only the filename - */ - transform(value: string): string { - let split1 = value.split('/'); - let split2 = split1[split1.length - 1].split('?'); - - return split2[split2.length - 1]; - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/image-dialog/mediaview.image-dialog.component.html b/projects/wave-core/src/lib/datatable/mediaview/image-dialog/mediaview.image-dialog.component.html deleted file mode 100644 index b1926c11..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/image-dialog/mediaview.image-dialog.component.html +++ /dev/null @@ -1,38 +0,0 @@ -
- - - - - - - open_in_new - - - - - - - - -
-
- -
-
-
- -
- - - -
-
diff --git a/projects/wave-core/src/lib/datatable/mediaview/image-dialog/mediaview.image-dialog.component.scss b/projects/wave-core/src/lib/datatable/mediaview/image-dialog/mediaview.image-dialog.component.scss deleted file mode 100644 index 03b8329d..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/image-dialog/mediaview.image-dialog.component.scss +++ /dev/null @@ -1,92 +0,0 @@ -$mat-dialog-padding: 24px !default; // TODO: import when this is possible again -$mat-fab-size: 56px !default; // TODO: import when this is possible again - -/*.previous{ - position: absolute; - top: calc(50% - #{$mat-fab-size/2}); - left: #{-$mat-fab-size/2}; -} - -.next{ - position: absolute; - top: calc(50% - #{$mat-fab-size/2}); - right: #{-$mat-fab-size/2}; -}*/ - -.imageContainer { - max-width: calc(100vw - 4rem); - max-height: calc(100vh - 4rem); - display: flex; - flex-direction: column; - margin: #{-$mat-dialog-padding}; - - img { - margin: 0 auto; - display: block; - } - - mat-dialog-content { - padding: 0; - margin: 0; - max-height: inherit; - max-width: inherit; - overflow: auto; - position: relative; - } - - mat-toolbar { - margin: 0; - - /*h3 small{ - overflow: hidden; - text-overflow: ellipsis; - word-break: keep-all; - }*/ - - .separator { - flex-grow: 1; - } - - .externalLink { - margin-right: 2rem; - } - - .closeLink { - } - } - - .loading { - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - background: rgba(#ffffff, 50%); - - .spinner { - position: relative; - top: calc(50% - 100px); - left: calc(50% - 100px); - } - } - - .buttons { - position: fixed; - bottom: 2 * $mat-dialog-padding; - left: 0; - width: 100%; - text-align: center; - - button { - margin: 1rem; - } - - .previous { - margin-right: 2rem; - } - - .next { - margin-left: 2rem; - } - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/image-dialog/mediaview.image-dialog.component.ts b/projects/wave-core/src/lib/datatable/mediaview/image-dialog/mediaview.image-dialog.component.ts deleted file mode 100644 index af2de3ac..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/image-dialog/mediaview.image-dialog.component.ts +++ /dev/null @@ -1,76 +0,0 @@ -import {Component, Input} from '@angular/core'; -import {MatDialogRef} from '@angular/material/dialog'; - -@Component({ - selector: 'wave-mediaview-image-dialog', - templateUrl: './mediaview.image-dialog.component.html', - styleUrls: ['./mediaview.image-dialog.component.scss'], -}) - -/** - * Dialog-Image-Component - * Is shown as a dialog-popup. - * Displays an image-gallery. One image is shown at a time with two buttons to the previous and next images in the list. - * The component receives an array of urls to images (imageURLS) and the id of the image to show first (currentImage) as inputs. - */ -export class MediaviewImageDialogComponent { - /** - * Input: An array of image-urls to display in the dialog - */ - @Input() - public imageURLs: string[]; - - /** - * Input: The index of the image to show first - */ - @Input() - public currentImage: number; - - public loading = true; - - // private domNode; - - /** - * Sets up all variables - * @param dialogRef reference to this Dialog-Type - */ - constructor(public dialogRef: MatDialogRef) { - // , @Inject(ElementRef) elementRef: ElementRef - this.loading = true; - - // this.domNode = elementRef.nativeElement; - } - - /** - * Hack to set Dialog's parent's position to absolute - */ - /*ngAfterViewInit() { - // console.log(this.domNode.parentNode); - - //this.domNode.parentNode.parentElement.style.position = 'relative'; - }*/ - - /** - * Shows the next image in the list of image-urls - */ - public nextImage() { - this.currentImage = (this.currentImage + 1) % this.imageURLs.length; - this.loading = true; - } - - /** - * Shows the previous image in the list of image-urls - */ - public previousImage() { - this.currentImage = this.currentImage <= 0 ? this.imageURLs.length - 1 : this.currentImage - 1; - this.loading = true; - } - - /** - * Called when the image has finished loading - * Updates the loading-variable (to hide the loading-spinner) - */ - public imageLoaded() { - this.loading = false; - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/image/mediaview.image.component.html b/projects/wave-core/src/lib/datatable/mediaview/image/mediaview.image.component.html deleted file mode 100644 index 863ac354..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/image/mediaview.image.component.html +++ /dev/null @@ -1,35 +0,0 @@ -Image {{ currentImage + 1 }} of {{ imageURLs.length }} - -
- - - - -
-
- -
-
- -
-

{{ imageURLs[currentImage] | fileName }}

- - - open_in_new - -
- -
- - - - - -
-
diff --git a/projects/wave-core/src/lib/datatable/mediaview/image/mediaview.image.component.scss b/projects/wave-core/src/lib/datatable/mediaview/image/mediaview.image.component.scss deleted file mode 100644 index 5cefc85d..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/image/mediaview.image.component.scss +++ /dev/null @@ -1,66 +0,0 @@ -$mat-icon-button-size: 40px !default; // TODO: import when this is possible again -$mat-fab-size: 56px !default; // TODO: import when this is possible again - -.imageContainer { - position: relative; - width: 100%; - height: 100%; - - mat-card { - width: calc(100% - 2rem); - margin: 1rem; - padding: 0; - } - - img { - width: 100%; - height: auto; - display: block; - } - - .loading { - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - background: fade_out(#ffffff, 0.5); - - .spinner { - position: relative; - top: calc(50% - 50px); - left: calc(50% - 50px); - } - } - - .info { - margin-bottom: calc(1rem + #{$mat-fab-size}); - width: 100%; - float: left; - - h3 { - float: left; - margin: 1rem; - width: calc(100% - 4rem - #{$mat-icon-button-size}); - overflow: hidden; - text-overflow: ellipsis; - word-break: keep-all; - } - - .externalLink { - float: right; - margin: 1rem; - } - } - - .buttons { - bottom: 0; - left: 0; - width: 100%; - text-align: center; - - button { - margin: 1rem; - } - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/image/mediaview.image.component.ts b/projects/wave-core/src/lib/datatable/mediaview/image/mediaview.image.component.ts deleted file mode 100644 index 969a64c2..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/image/mediaview.image.component.ts +++ /dev/null @@ -1,79 +0,0 @@ -import {Component, Input, ViewContainerRef} from '@angular/core'; -import {MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material/dialog'; -import {MediaviewImageDialogComponent} from '../image-dialog/mediaview.image-dialog.component'; - -@Component({ - selector: 'wave-mediaview-image', - templateUrl: './mediaview.image.component.html', - styleUrls: ['./mediaview.image.component.scss'], -}) - -/** - * Dialog-Image-Component - * Is shown as a dialog-popup. - * Displays an image-gallery. One image is shown at a time with two buttons to the previous and next images in the list. - * The component receives an array of urls to images (imageURLS) and the id of the image to show first (currentImage) as inputs. - */ -export class MediaviewImageComponent { - /** - * Input: An array of image-urls to display in the dialog - */ - @Input() - public imageURLs: string[]; - - /** - * Input: The index of the image to show first - */ - @Input() - public currentImage: number; - - public loading = true; - - private dialogRef: MatDialogRef; - - /** - * Sets up all variables - * @param dialog reference to MDDialog - * @param viewContainerRef reference to ViewContainer - */ - constructor(private dialog: MatDialog, private viewContainerRef: ViewContainerRef) {} - - /** - * Shows the next image in the list of image-urls - */ - public nextImage() { - this.currentImage = (this.currentImage + 1) % this.imageURLs.length; - this.loading = true; - } - - /** - * Shows the previous image in the list of image-urls - */ - public previousImage() { - this.currentImage = this.currentImage <= 0 ? this.imageURLs.length - 1 : this.currentImage - 1; - this.loading = true; - } - - /** - * Called when the image has finished loading - * Updates the loading-variable (to hide the loading-spinner) - */ - public imageLoaded() { - this.loading = false; - } - - /** - * Opens a dialog-popup, showing the images in full size - */ - public openImageFullSize() { - let config = new MatDialogConfig(); - config.viewContainerRef = this.viewContainerRef; - - this.dialogRef = this.dialog.open(MediaviewImageDialogComponent, config); - - this.dialogRef.componentInstance.imageURLs = this.imageURLs; - this.dialogRef.componentInstance.currentImage = this.currentImage; - - this.dialogRef.afterClosed().subscribe(() => (this.dialogRef = null)); - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/mediaview.component.html b/projects/wave-core/src/lib/datatable/mediaview/mediaview.component.html deleted file mode 100644 index 65f0c3e9..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/mediaview.component.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - image{{ imageUrls.length }} imageimages - - - music_video{{ audioUrls.length }} - audio-fileaudio-files - - - movie{{ videoUrls.length }} videovideos - - - - {{ u }}, - - - diff --git a/projects/wave-core/src/lib/datatable/mediaview/mediaview.component.scss b/projects/wave-core/src/lib/datatable/mediaview/mediaview.component.scss deleted file mode 100644 index 67db6fb1..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/mediaview.component.scss +++ /dev/null @@ -1,5 +0,0 @@ -mat-icon { - vertical-align: text-top; - height: 20px; - line-height: 20px; -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/mediaview.component.ts b/projects/wave-core/src/lib/datatable/mediaview/mediaview.component.ts deleted file mode 100644 index edd9909d..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/mediaview.component.ts +++ /dev/null @@ -1,177 +0,0 @@ -import {Component, Input, OnChanges, ChangeDetectionStrategy} from '@angular/core'; -import {MediaviewImageComponent} from './image/mediaview.image.component'; -import {MediaviewAudioComponent} from './audio/mediaview.audio.component'; -import {MediaviewVideoComponent} from './video/mediaview.video.component'; -import {LayoutService} from '../../layout.service'; - -@Component({ - selector: 'wave-datatable-mediaview', - templateUrl: './mediaview.component.html', - styleUrls: ['./mediaview.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) - -/** - * Dialog-Component - * Checks the file-type of the comma-separated urls given as input-argument and sets up links to open dialogs. - * The dialogs will show the images or play the audios or videos - */ -export class MediaviewComponent implements OnChanges { - private urls: string[]; - public mediaType: string[]; - - public imageUrls: string[]; - public audioUrls: string[]; - public videoUrls: string[]; - public textNoUrls: string[]; - - /** - * Input: A List of comma-separated urls to images, audio-files and videos - */ - @Input() - private url: any; - - /** - * Input: Type of the audio urls (text, media or none) - */ - @Input() - private type: string; - - /** - * Extracts the type (image, audio, video) of a given file-url - * @param value url containing the filename with file-ending - * @returns {string} the type of the file or an empty string if there is no file-ending - */ - public static getType(value: string): string { - let ret: string; - - if (value !== '') { - let dotSplits = value.split('.'); - - if (dotSplits.length > 1) { - let fileEnding = dotSplits[dotSplits.length - 1].toLowerCase(); - - switch (fileEnding) { - // Image - case 'jpg': - case 'jpeg': - case 'gif': - case 'png': - case 'svg': - case 'bmp': - ret = 'image'; - break; - - // Audio - case 'wav': - case 'mp3': - case 'ogg': - case 'aac': - ret = 'audio'; - break; - - // Video - case 'mp4': - case 'webm': - case 'ogv': - ret = 'video'; - break; - - // None - default: - ret = 'text'; - } - } else { - ret = 'text'; - } - } else { - ret = ''; - } - // console.log(ret); - return ret; - } - - /** - * Sets up all variables - * @param layoutService reference to LayoutService - */ - constructor(public layoutService: LayoutService) {} - - /** - * OnChange - * Calculates the file-type of the comma-separated urls given as input-argument - */ - ngOnChanges() { - if (this.type === 'media') { - this.urls = this.url.split(','); - this.mediaType = new Array(this.urls.length); - - this.imageUrls = []; - this.audioUrls = []; - this.videoUrls = []; - this.textNoUrls = []; - - for (let i in this.urls) { - if (this.urls.hasOwnProperty(i)) { - this.mediaType[i] = MediaviewComponent.getType(this.urls[i]); - // console.log(this.mediaType[i]); - - if (this.mediaType[i] !== '') { - this.urls[i] = this.urls[i].trim(); - } - - if (this.mediaType[i] === 'image') { - this.imageUrls.push(this.urls[i]); - } else if (this.mediaType[i] === 'audio') { - this.audioUrls.push(this.urls[i]); - } else if (this.mediaType[i] === 'video') { - this.videoUrls.push(this.urls[i]); - } else { - this.textNoUrls.push(this.urls[i]); - } - } - } - } else { - this.urls = [this.url.toString()]; - this.mediaType = ['']; - - this.imageUrls = []; - this.audioUrls = []; - this.videoUrls = []; - this.textNoUrls = [this.url.toString()]; - } - } - - /** - * Opens the images in the sidenav - * @param imageID the ID of the first image to be shown - */ - public openImageMediaview(imageID: number) { - this.layoutService.setSidenavContentComponent({ - component: MediaviewImageComponent, - config: {imageURLs: this.imageUrls, currentImage: imageID}, - }); - } - - /** - * Opens the audio-files in the sidenav - * @param audioID the ID of the first audio-file to be played - */ - public openAudioMediaview(audioID: number) { - this.layoutService.setSidenavContentComponent({ - component: MediaviewAudioComponent, - config: {audioURLs: this.audioUrls, currentAudio: audioID}, - }); - } - - /** - * Opens the videos in the sidenav - * @param videoID the ID of the first video to be played - */ - public openVideoMediaview(videoID: number) { - this.layoutService.setSidenavContentComponent({ - component: MediaviewVideoComponent, - config: {videoURLs: this.videoUrls, currentVideo: videoID}, - }); - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/playlist/mediaview.playlist.component.html b/projects/wave-core/src/lib/datatable/mediaview/playlist/mediaview.playlist.component.html deleted file mode 100644 index c2f98c56..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/playlist/mediaview.playlist.component.html +++ /dev/null @@ -1,18 +0,0 @@ - -

Files

- - - - - radio_button_checked - radio_button_unchecked - -

- {{ u | fileName }} -

- - - open_in_new - -
-
diff --git a/projects/wave-core/src/lib/datatable/mediaview/playlist/mediaview.playlist.component.scss b/projects/wave-core/src/lib/datatable/mediaview/playlist/mediaview.playlist.component.scss deleted file mode 100644 index 93b392b4..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/playlist/mediaview.playlist.component.scss +++ /dev/null @@ -1,7 +0,0 @@ -mat-nav-list { - clear: both; -} - -.playing { - font-weight: bold; -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/playlist/mediaview.playlist.component.ts b/projects/wave-core/src/lib/datatable/mediaview/playlist/mediaview.playlist.component.ts deleted file mode 100644 index 38fe3960..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/playlist/mediaview.playlist.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {Component, Input, Output, EventEmitter} from '@angular/core'; - -@Component({ - selector: 'wave-mediaview-playlist', - templateUrl: './mediaview.playlist.component.html', - styleUrls: ['./mediaview.playlist.component.scss'], -}) - -/** - * Playlist-Component - * Is used in the audio- and video-dialog-popups. - * Displays a playlist showing all files in the given list and highlights the file currently playing. - * The component receives an array of urls (tracks) and the id of the one currently playing (currentTrack) as inputs. - * It has an Event-Emitter as Output that is fired when a playlist-item is clicked to be played - */ -export class MediaviewPlaylistComponent { - /** - * Input: An array of urls to show in the playlist - */ - @Input() - public tracks: string[]; - - /** - * Input: The index of the track currently playing - */ - @Input() - public currentTrack: number; - - /** - * Output: Emitted when a link in the playlist is clicked to change the track. The track-id of the track to play is emitted - * @type {EventEmitter} - */ - @Output() - public gotoTrack: EventEmitter = new EventEmitter(); - - /** - * Emits an event, telling the parent component that the track with the given id should be played - * and the currently playing one shall be skipped - * @param trackID the ID of the track to play - */ - public goToTrack(trackID: number) { - this.gotoTrack.emit(trackID); - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/video/mediaview.video.component.html b/projects/wave-core/src/lib/datatable/mediaview/video/mediaview.video.component.html deleted file mode 100644 index 2c1fb167..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/video/mediaview.video.component.html +++ /dev/null @@ -1,17 +0,0 @@ -Video {{ currentVideo + 1 }} of {{ videoURLs.length }} - -
- - - - -
-

{{ videoURLs[currentVideo] | fileName }}

- - - open_in_new - -
- - -
diff --git a/projects/wave-core/src/lib/datatable/mediaview/video/mediaview.video.component.scss b/projects/wave-core/src/lib/datatable/mediaview/video/mediaview.video.component.scss deleted file mode 100644 index 8fdc8f81..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/video/mediaview.video.component.scss +++ /dev/null @@ -1,34 +0,0 @@ -$mat-icon-button-size: 40px !default; // TODO: import when this is possible again - -.videoContainer { - mat-card { - width: calc(100% - 2rem); - margin: 1rem; - padding: 0; - } - - video { - width: 100%; - margin: 0; - display: block; - } - - .info { - float: left; - width: 100%; - - h3 { - float: left; - margin: 1rem; - width: calc(100% - 4rem - #{$mat-icon-button-size}); - overflow: hidden; - text-overflow: ellipsis; - word-break: keep-all; - } - - .externalLink { - float: right; - margin: 1rem; - } - } -} diff --git a/projects/wave-core/src/lib/datatable/mediaview/video/mediaview.video.component.ts b/projects/wave-core/src/lib/datatable/mediaview/video/mediaview.video.component.ts deleted file mode 100644 index 0b6d64ff..00000000 --- a/projects/wave-core/src/lib/datatable/mediaview/video/mediaview.video.component.ts +++ /dev/null @@ -1,48 +0,0 @@ -import {Component, Input} from '@angular/core'; -import {SidenavHeaderComponent} from '../../../sidenav/sidenav-header/sidenav-header.component'; - -@Component({ - selector: 'wave-mediaview-video', - templateUrl: './mediaview.video.component.html', - styleUrls: ['./mediaview.video.component.scss'], -}) - -/** - * Dialog-Video-Component - * Is shown as a dialog-popup. - * Displays a video-player with a playlist. - * The component receives an array of urls to video-files (videoURLS) and the id of the video to play first (currentVideo) as inputs. - */ -export class MediaviewVideoComponent { - /** - * Input: An array of video-urls to display in the dialog - */ - @Input() - public videoURLs: string[]; - - /** - * Input: The index of the video to play first - */ - @Input() - public currentVideo: number; - - public autoPlay: boolean; - - /** - * Plays the video with given id, skipping the currently playing one - * @param videoID the ID auf the video-file to play - */ - public goToVideo(videoID: number) { - this.currentVideo = videoID; - this.autoPlay = true; - } - - /** - * Plays the next video in the list of video-urls - * If the current file is the last one, plays the first one - * Is called when the current video has finished playing - */ - public playNext() { - this.goToVideo((this.currentVideo + 1) % this.videoURLs.length); - } -} diff --git a/projects/wave-core/src/lib/datatable/table/table.component.html b/projects/wave-core/src/lib/datatable/table/table.component.html deleted file mode 100644 index 81efc7b2..00000000 --- a/projects/wave-core/src/lib/datatable/table/table.component.html +++ /dev/null @@ -1,80 +0,0 @@ -
- -
-
- -
-
- - - - - - - - - - - - - - - - - {{ dataHeadUnits[j] }} - - - - - - {{ element.properties[t] }} - - - - - - - - - - -
- no layer selected -
-
diff --git a/projects/wave-core/src/lib/datatable/table/table.component.scss b/projects/wave-core/src/lib/datatable/table/table.component.scss deleted file mode 100644 index 7dc1920d..00000000 --- a/projects/wave-core/src/lib/datatable/table/table.component.scss +++ /dev/null @@ -1,121 +0,0 @@ -:host { - font-size: 0.87rem; -} - -.scrollContent { - overflow: auto; - width: 100%; - position: relative; - overflow-anchor: none; -} - -.mat-table { - float: left; -} - -.tableFixed { - position: relative; - background: fade-out(#ffffff, 0.1); -} - -.mat-header-row, -.mat-row { - min-height: 40px; - padding-left: 0; -} - -.mat-header-row.tableFixedHorizontal { - z-index: 11; -} - -.mat-header-cell, -.mat-cell { - height: 36px; - - &:not(.tableFixedVertical) { - overflow: hidden; - word-wrap: break-word; - hyphens: auto; - text-overflow: ellipsis; - padding: 2px 5px; - } - - &.tableFixedVertical { - padding: 2px 14px; - display: flex; - align-items: center; - } -} - -.mat-header-cell.tableFixedVertical { - z-index: 12; -} - -.mat-cell.tableFixedVertical { - z-index: 10; - min-width: 20px; - max-width: 20px; -} - -.mat-cell span { - height: 36px; - display: block; - overflow: hidden; - text-overflow: ellipsis; -} - -.rowSelected { - background: var(--wave-faded-accent-color, grey); - - .tableFixed::before { - content: ' '; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: var(--wave-faded-accent-color, grey); - } -} - -.offsetterTop, -.offsetterBottom { - padding: 0; - border: 0; - min-height: 0; - height: 0; - - .mat-cell { - height: 0; - padding: 0; - } -} - -.no-layer { - display: table; - width: 100%; - height: 100%; - text-align: center; - color: var(--wave-foreground-secondary-text-color, black); - - span { - display: table-cell; - vertical-align: middle; - } -} - -.spinnerContainer { - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - background: fade-out(#ffffff, 0.3); - z-index: 10; - - .spinner { - position: absolute; - top: calc(50% - 50px); - left: calc(50% - 50px); - } -} diff --git a/projects/wave-core/src/lib/datatable/table/table.component.ts b/projects/wave-core/src/lib/datatable/table/table.component.ts deleted file mode 100644 index 1161244d..00000000 --- a/projects/wave-core/src/lib/datatable/table/table.component.ts +++ /dev/null @@ -1,606 +0,0 @@ -import {BehaviorSubject, combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription} from 'rxjs'; -import {map, switchMap} from 'rxjs/operators'; - -import { - AfterViewInit, - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - ElementRef, - Input, - OnChanges, - OnDestroy, - OnInit, - SimpleChanges, - ViewChild, -} from '@angular/core'; -import {DataSource} from '@angular/cdk/collections'; -import {MediaviewComponent} from '../mediaview/mediaview.component'; -import {LayerService} from '../../layers/layer.service'; -import {LoadingState} from '../../project/loading-state.model'; -import {ResultTypes} from '../../operators/result-type.model'; -import {Layer, VectorData, VectorLayer} from '../../layers/layer.model'; -import {AbstractVectorSymbology} from '../../layers/symbology/symbology.model'; -import {FeatureID} from '../../queries/geojson.model'; -import {MapService} from '../../map/map.service'; -import {ProjectService} from '../../project/project.service'; -import {Unit} from '../../operators/unit.model'; -import {Feature as OlFeature} from 'ol/Feature'; -import {Point as OlPoint} from 'ol/geom/Point'; - -/** - * Data-Table-Component - * Displays a Data-Table - */ -@Component({ - selector: 'wave-datatable', - templateUrl: './table.component.html', - styleUrls: ['table.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -/** - * Data-Table-Component - * Displays a Data-Table - */ -export class TableComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit { - public LoadingState = LoadingState; - - @Input() - public height: number; - - // Data and Data-Subsets - public data: Array<{id: string | number; properties: {[key: string]: any}}>; - public tableData: TableDataSource; - public dataHead: Array; - public tableDataHead: Array; - public dataHeadUnits: Array; - - // For row-selection - public selected: boolean[]; - public allSelected: boolean; - public allEqual: boolean; - - // Element-References - @ViewChild('scrollContainer', {static: true}) public container: ElementRef; - - public data$: Observable>; - public state$: Observable; - - public offsetTop$: BehaviorSubject; - public offsetBottom$: BehaviorSubject; - - public avgWidths: number[]; - public colTypes: string[]; - - // For virtual scrolling - public scrollTop = 0; - public scrollLeft = 0; - - public displayItemCount: number; - - public displayItemCounter: number[]; - - public firstDisplay: number; - - private displayOffsetMin = 1; - - private scrolling = false; - - private scrollTopBefore = 0; - - private elementHeight = 41; - private headerHeight = 41; - - private minDisplayItemCount = 6; - - private selectable$: Observable; - private dataSubscription: Subscription; - private featureSubscription: Subscription; - - // For text-width-calculation - private styleString = '16px Roboto, sans-serif'; - private styleStringHead = '12px Roboto, sans-serif'; - private columnMinWidth = 100; - private columnMaxWidth = 400; - private canvas; - - /** - * Returns all the keys of an object as array - * @param object the object containing the keys - * @returns {string[]} a string-array containing all the keys - */ - private static getArrayOfKeys(object: {[key: string]: any}): Array { - return Object.keys(object).filter((x) => !(x.startsWith('___') || x === 'geometry')); - } - - /** - * Checks if the given unit is the default unit. If so returns an empty string, if not returns the unit formated for the header - * @param x the unit to display - * @returns {string} the formated unit-string - */ - private static formatUnits(x: Unit): string { - if (x && x.unit !== Unit.defaultUnit.unit) { - return ' [' + x.unit + ']'; - } else { - return ''; - } - } - - /** - * Sets up all variables - * Extracts the column names from the data input and calculates the average widths of all rows - * @param cdr ChangeDetector Reference - * @param layerService LayerService Reference - * @param mapService MapService Reference - * @param projectService ProjectService Reference - */ - constructor( - private cdr: ChangeDetectorRef, - public layerService: LayerService, - private mapService: MapService, - private projectService: ProjectService, - ) { - this.canvas = document.createElement('canvas'); - - this.displayItemCount = this.minDisplayItemCount; - - this.initDataStream(); - } - - ngOnInit() { - this.dataSubscription = this.data$.subscribe((features: Array) => { - this.dataHead = []; - this.dataHeadUnits = []; - this.tableDataHead = []; - - this.data = features.map((x) => { - return { - id: x.getId(), - properties: x.getProperties(), - }; - }); - - if (this.height / this.elementHeight > this.minDisplayItemCount) { - this.displayItemCount = Math.ceil((1.5 * this.height) / this.elementHeight); - } - - // console.log(this.data); - - // only needs to be called once for each "data" - this.dataInit(); - - this.cdr.markForCheck(); - }); - } - - /** - * Get the height of the container and save it to variable - */ - ngAfterViewInit() { - this.featureSubscription = this.layerService.getSelectedFeaturesStream().subscribe((x) => { - for (let i = 0; i < this.data.length; i++) { - const selectedContainsId = x.selected.contains(this.data[i].id); - if (!this.selected[i] && selectedContainsId) { - this.container.nativeElement.scrollTop = i * this.elementHeight; - } - - this.selected[i] = selectedContainsId; - } - - this.testSelected(); - this.testEqual(); - - this.cdr.markForCheck(); - }); - } - - ngOnChanges(changes: SimpleChanges) { - if (this.height / this.elementHeight > this.minDisplayItemCount) { - this.displayItemCount = Math.ceil((1.5 * this.height) / this.elementHeight); - } - } - - ngOnDestroy() { - this.dataSubscription.unsubscribe(); - this.featureSubscription.unsubscribe(); - } - - private initDataStream(): void { - const dataStream: Observable<{ - data$: Observable; - state$: Observable; - selectable: boolean; - }> = this.layerService.getSelectedLayerStream().pipe( - map((layer) => { - if (layer instanceof Layer) { - switch (layer.operator.resultType) { - case ResultTypes.POINTS: - case ResultTypes.LINES: - case ResultTypes.POLYGONS: - let vectorLayer = layer as VectorLayer; - let vectorLayerData = this.projectService.getLayerDataStream(vectorLayer) as Observable; - - const data = observableCombineLatest(vectorLayerData, this.mapService.getViewportSizeStream()).pipe( - map(([d, v]) => { - return d.data.filter((x) => { - const ve = v.extent; - - // console.log(ve, x.getGeometry(), int); - return (x.getGeometry() as OlPoint).intersectsExtent(ve); // TODO: not only point - }); - }), - ); - return { - data$: data, - dataExtent$: vectorLayerData.pipe(map((x) => x.extent)), - state$: this.projectService.getLayerDataStatusStream(vectorLayer), - selectable: true, - }; - default: - return { - data$: observableOf([]), - state$: observableOf(LoadingState.OK), - selectable: false, - }; - } - } else { - return { - data$: observableOf([]), - state$: observableOf(LoadingState.OK), - selectable: false, - }; - } - }), - ); - - // FIXME: use the correct datatype? - this.data$ = dataStream.pipe(switchMap((stream) => stream.data$)); - this.state$ = dataStream.pipe(switchMap((stream) => stream.state$)); - this.selectable$ = dataStream.pipe(map((stream) => stream.selectable)); - } - - /** - * Called when the input-variable data has changed - * Resets and recalculates all variables needed for displaying data in the table, virtual scrolling and selection - */ - private dataInit(): void { - this.firstDisplay = 0; - - this.tableData = new TableDataSource(this.data, this.firstDisplay, this.displayItemCount); - - this.container.nativeElement.scrollTop = 0; - this.container.nativeElement.scrollLeft = 0; - - this.offsetTop$ = new BehaviorSubject(0); - let offsetBottom = (this.data.length - this.displayItemCount) * this.elementHeight; - if (offsetBottom < 0) { - offsetBottom = 0; - } - this.offsetBottom$ = new BehaviorSubject(offsetBottom); - - // Reset selection - this.selected = []; - for (let i = 0; i < this.data.length; i++) { - this.selected[i] = false; - } - - // Get Header - if (this.data.length > 0 && this.data[0].properties) { - this.dataHead = TableComponent.getArrayOfKeys(this.data[0].properties); - this.tableDataHead = ['selection', ...this.dataHead]; - } - - // console.log(this.dataHead); - if (this.layerService) { - if (this.layerService.getSelectedLayer()) { - let units = this.layerService.getSelectedLayer().operator.units; - - if (units) { - this.dataHeadUnits = []; - - for (let d in this.dataHead) { - if (this.dataHead.hasOwnProperty(d)) { - this.dataHeadUnits.push(this.dataHead[d] + TableComponent.formatUnits(units.get(this.dataHead[d]))); - } - } - } - } - } - - // Reset avg widths - this.avgWidths = []; - for (let i = 0; i < this.data.length; i++) { - this.avgWidths[i] = this.columnMinWidth; - } - - // Calculate Column widths - const testData = this.selectRandomSubData(20); - [this.avgWidths, this.colTypes] = this.calculateColumnProperties(testData, this.dataHead, this.dataHeadUnits); - - /*console.log('--------------------------------'); - console.log(testData); - console.log(this.avgWidths);*/ - - // Recreate displayItemCounter - this.displayItemCounter = []; - let j = 0; - while (this.displayItemCounter.length < this.displayItemCount && this.displayItemCounter.length < this.data.length) { - this.displayItemCounter.push(j); - j++; - } - - // Test for Selections - this.testSelected(); - this.testEqual(); - } - - /** - * Uses canvas.measureText to compute and return the width of the given text of given font in pixels. - * - * @param {String} text The text to be rendered. - * @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana"). - * @returns {number} the calculated width - */ - private getTextWidth(text, font): number { - // re-use canvas object for better performance - let context = this.canvas.getContext('2d'); - context.font = font; - let metrics = context.measureText(text); - // console.log(metrics); - return metrics.width; - } - - /** - * Selects a given number of random rows from the main dataset - * @param number amount of rows to select - * @returns {Array} an array of rows from the dataset - */ - private selectRandomSubData(number): Array { - let testData = []; - - for (let i = 0; i < number; i++) { - let r = Math.floor(Math.random() * this.data.length); - - testData[i] = this.data[r]; - } - - return testData; - } - - /** - * Calculates the average column-text-widths of a given dataset. Also includes the header-texts to make shure they also fit - * Tests for the contents of the sample-data to predict the content type of each column - * @param testData the dataset, to calculate column widths from - * @param dataHead the column names of the given dataset - * @param dataHeadUnits the column names of the given dataset (with units) - * @returns ({Array},{Array}) an array of average-widths and an array with the predicted content types - */ - private calculateColumnProperties(testData, dataHead, dataHeadUnits): [number[], string[]] { - let headCount = dataHead.length; - - let widths = []; - let types = []; - - for (let column = 0; column < headCount; column++) { - let columnWidth = 0; - let columnType; - - // Header Row - columnWidth = this.getTextWidth(dataHeadUnits[column], this.styleStringHead); - - columnType = 'text'; - - for (let row = 0; row < testData.length; row++) { - // Normal Table Rows - let tmp = testData[row].properties[dataHead[column]]; - - // console.log(tmp); - - if (typeof tmp === 'string' && tmp !== '') { - let urls = tmp.split(/(,)/g); - - let mediaCount = [0, 0, 0]; - let nonUrlsString = ''; - - for (let u in urls) { - if (urls.hasOwnProperty(u)) { - let mediaType = MediaviewComponent.getType(urls[u]); - - if (mediaType !== '') { - if (mediaType === 'text') { - nonUrlsString += urls[u] + ' '; - } else { - if (mediaType === 'image') { - mediaCount[0] += 1; - } else if (mediaType === 'audio') { - mediaCount[1] += 1; - } else if (mediaType === 'video') { - mediaCount[2] += 1; - } - - columnType = 'media'; - } - } - } - } - - let mediaString = ''; - - if (mediaCount[0] > 0) { - mediaString += '___ ' + mediaCount[0] + ' images'; - } - if (mediaCount[1] > 0) { - mediaString += '___ ' + mediaCount[1] + ' audio-files'; - } - if (mediaCount[2] > 0) { - mediaString += '___ ' + mediaCount[2] + ' videos'; - } - - mediaString += ' ' + nonUrlsString; - - // console.log(mediaString); - - columnWidth = Math.max(columnWidth, this.getTextWidth(mediaString, this.styleString)); - } - } - - // Widths - if (columnWidth > this.columnMaxWidth) { - columnWidth = this.columnMaxWidth; - } - widths[column] = columnWidth; - - // Types - types[column] = columnType; - } - - return [widths, types]; - } - - /** - * Called on Scrolling the Data-Table - * Updates the auto-scrolling first row and first column and calls the virtual-scroll update functions (top and bottom) - */ - public updateScroll(): void { - this.scrollTopBefore = this.scrollTop; - // this.scrollLeftBefore = this.scrollLeft; - - this.scrollTop = this.container.nativeElement.scrollTop; - this.scrollLeft = this.container.nativeElement.scrollLeft; - // console.log(this.scrollTopBefore+"->"+this.scrollTop); - - if (this.data != null && !this.scrolling) { - this.scrolling = true; - - let numberOfTopRows; - - // Scrolling down - if (this.scrollTop > this.scrollTopBefore) { - if ( - this.scrollTop + this.height > - this.headerHeight + (this.firstDisplay + this.displayItemCount - this.displayOffsetMin) * this.elementHeight - ) { - numberOfTopRows = Math.floor((this.scrollTop - this.headerHeight) / this.elementHeight) - this.displayOffsetMin; - } - } - - // Scrolling up - if (this.scrollTop < this.scrollTopBefore) { - if (this.scrollTop < this.headerHeight + (this.firstDisplay + this.displayOffsetMin) * this.elementHeight) { - numberOfTopRows = - Math.floor((this.scrollTop + this.height) / this.elementHeight) + this.displayOffsetMin - this.displayItemCount; - } - } - - if (typeof numberOfTopRows !== 'undefined') { - if (numberOfTopRows + this.displayItemCount > this.data.length) { - numberOfTopRows = this.data.length - this.displayItemCount; - } - if (numberOfTopRows < 0) { - numberOfTopRows = 0; - } - - if (this.firstDisplay !== numberOfTopRows) { - this.firstDisplay = numberOfTopRows; - this.tableData.update(this.data, this.firstDisplay, this.displayItemCount); - - this.offsetBottom$.next((this.data.length - numberOfTopRows - this.displayItemCount) * this.elementHeight); - this.offsetTop$.next(numberOfTopRows * this.elementHeight); - } - } - - this.scrolling = false; - } - } - - /** - * Row-Selection - * Called on clicking a checkbox to select a row - * toggles the checked-variable for this row and runs the tests to check, whether all rows are selected or unselected - */ - public toggle(index: number): void { - this.selected[index] = !this.selected[index]; - - if (this.selected[index]) { - this.layerService.updateSelectedFeatures([this.data[index].id], []); - } else { - this.layerService.updateSelectedFeatures([], [this.data[index].id]); - } - } - - /** - * Row-Selection - * Called when clicking the select-all-checkbox - * Selects or unselects all rows, depending on whether a row is already selected - */ - public toggleAll(): void { - let toggledList = Array(); - for (let i = 0; i < this.selected.length; i++) { - if (this.allSelected === this.selected[i]) { - toggledList.push(this.data[i].id); - } - - this.selected[i] = !this.allSelected; - } - - if (!this.allSelected) { - this.layerService.updateSelectedFeatures(toggledList, []); - } else { - this.layerService.updateSelectedFeatures([], toggledList); - } - } - - /** - * Row-Selection - * Tests, if all Rows are selected and sets the global allSelected variable - * Also emits the row-selection-event - */ - private testSelected(): void { - this.allSelected = true; - for (let s of this.selected) { - if (!s) { - this.allSelected = false; - break; - } - } - } - - /** - * Row-Selection - * Tests, if all Rows are in equal state (all selected or all unselected) and sets the global allEqual variable - */ - private testEqual(): void { - this.allEqual = true; - for (let s of this.selected) { - if (s !== this.selected[0]) { - this.allEqual = false; - break; - } - } - } -} - -export class TableDataSource extends DataSource { - private dataObs$: BehaviorSubject; - - constructor(data: Array, start: number, length: number) { - super(); - this.dataObs$ = new BehaviorSubject([]); - this.update(data, start, length); - } - - update(data: Array, start: number, length: number): void { - let slice = data.slice(start, start + length); - let dataNew = [undefined, ...slice, undefined]; - // console.log(start, length); - // console.log(this.data); - this.dataObs$.next(dataNew); - } - - /** Connect function called by the table to retrieve one stream containing the data to render. */ - connect(): Observable { - return this.dataObs$.asObservable(); - } - - disconnect() {} -} diff --git a/projects/wave-core/src/lib/dialogs/dialog-header/dialog-header.component.html b/projects/wave-core/src/lib/dialogs/dialog-header/dialog-header.component.html deleted file mode 100644 index f8f5ddf3..00000000 --- a/projects/wave-core/src/lib/dialogs/dialog-header/dialog-header.component.html +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/projects/wave-core/src/lib/dialogs/dialog-header/dialog-header.component.scss b/projects/wave-core/src/lib/dialogs/dialog-header/dialog-header.component.scss deleted file mode 100644 index 42e4bf5d..00000000 --- a/projects/wave-core/src/lib/dialogs/dialog-header/dialog-header.component.scss +++ /dev/null @@ -1,11 +0,0 @@ -$mat-dialog-padding: 24px !default; // TODO: import when this is possible again - -mat-toolbar.mat-dialog-title { - margin: #{-$mat-dialog-padding} #{-$mat-dialog-padding} 0 #{-$mat-dialog-padding}; - width: calc(100% + #{2 * $mat-dialog-padding}); -} - -mat-toolbar button { - padding: 0; - min-width: 2.25rem; -} diff --git a/projects/wave-core/src/lib/dialogs/dialog-header/dialog-header.component.ts b/projects/wave-core/src/lib/dialogs/dialog-header/dialog-header.component.ts deleted file mode 100644 index 386ef38c..00000000 --- a/projects/wave-core/src/lib/dialogs/dialog-header/dialog-header.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {Component, OnInit} from '@angular/core'; - -@Component({ - selector: 'wave-dialog-header', - templateUrl: './dialog-header.component.html', - styleUrls: ['./dialog-header.component.scss'], -}) -export class DialogHeaderComponent implements OnInit { - constructor() {} - - ngOnInit() {} -} diff --git a/projects/wave-core/src/lib/dialogs/dialog-help/dialog-help.component.html b/projects/wave-core/src/lib/dialogs/dialog-help/dialog-help.component.html deleted file mode 100644 index 811086c7..00000000 --- a/projects/wave-core/src/lib/dialogs/dialog-help/dialog-help.component.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - help -

Help

-
-
-
- -
-
diff --git a/projects/wave-core/src/lib/dialogs/dialog-help/dialog-help.component.scss b/projects/wave-core/src/lib/dialogs/dialog-help/dialog-help.component.scss deleted file mode 100644 index 82c304e9..00000000 --- a/projects/wave-core/src/lib/dialogs/dialog-help/dialog-help.component.scss +++ /dev/null @@ -1,22 +0,0 @@ -:host { - padding: 1rem; -} - -mat-panel-title { - align-items: center; -} - -mat-icon { - flex-grow: 0; -} - -.help-content ::ng-deep { - div, - p { - text-align: justify; - } -} - -.small_caps { - font-variant: small-caps; -} diff --git a/projects/wave-core/src/lib/dialogs/dialog-help/dialog-help.component.ts b/projects/wave-core/src/lib/dialogs/dialog-help/dialog-help.component.ts deleted file mode 100644 index 1ea7f32e..00000000 --- a/projects/wave-core/src/lib/dialogs/dialog-help/dialog-help.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-dialog-help', - templateUrl: './dialog-help.component.html', - styleUrls: ['./dialog-help.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class DialogHelpComponent implements OnInit { - constructor() {} - - ngOnInit() {} -} diff --git a/projects/wave-core/src/lib/dialogs/dialog-section-heading/dialog-section-heading.component.html b/projects/wave-core/src/lib/dialogs/dialog-section-heading/dialog-section-heading.component.html deleted file mode 100644 index c5b6ff4b..00000000 --- a/projects/wave-core/src/lib/dialogs/dialog-section-heading/dialog-section-heading.component.html +++ /dev/null @@ -1,4 +0,0 @@ -

- {{ title }} - {{ subtitle }} -

diff --git a/projects/wave-core/src/lib/dialogs/dialog-section-heading/dialog-section-heading.component.scss b/projects/wave-core/src/lib/dialogs/dialog-section-heading/dialog-section-heading.component.scss deleted file mode 100644 index 8a50b737..00000000 --- a/projects/wave-core/src/lib/dialogs/dialog-section-heading/dialog-section-heading.component.scss +++ /dev/null @@ -1,12 +0,0 @@ -:host { - display: block; -} - -h3 { - font-size: 1.17rem; - small { - display: block; - font-weight: normal; - } - margin: 1rem 0; -} diff --git a/projects/wave-core/src/lib/dialogs/dialog-section-heading/dialog-section-heading.component.ts b/projects/wave-core/src/lib/dialogs/dialog-section-heading/dialog-section-heading.component.ts deleted file mode 100644 index 42157eac..00000000 --- a/projects/wave-core/src/lib/dialogs/dialog-section-heading/dialog-section-heading.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {Component, Input, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-dialog-section-heading', - templateUrl: './dialog-section-heading.component.html', - styleUrls: ['./dialog-section-heading.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class DialogSectionHeadingComponent { - @Input('title') title: string; - @Input('subtitle') subtitle: string; -} diff --git a/projects/wave-core/src/lib/help/about/help-about.component.css b/projects/wave-core/src/lib/help/about/help-about.component.css deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/help/about/help-about.component.html b/projects/wave-core/src/lib/help/about/help-about.component.html deleted file mode 100644 index 34db1cff..00000000 --- a/projects/wave-core/src/lib/help/about/help-about.component.html +++ /dev/null @@ -1,18 +0,0 @@ - - About -

- Vat is developed by the Database Research Group of the University of Marburg (head: Prof. Bernhard Seeger) - in cooperation with the Senckenberg Biodiversity and Climate Research Centre (BiK-F) (head: Prof. Thomas Hickler). You can contact - us at vat@mathematik.uni-marburg.de or visit our - GitHub for further information. -

- - University of Marburg - - - Database Research Group of the University of Marburg - - - Senckenberg Society for Nature Research - -
diff --git a/projects/wave-core/src/lib/help/about/help-about.component.ts b/projects/wave-core/src/lib/help/about/help-about.component.ts deleted file mode 100644 index d0a2b3f7..00000000 --- a/projects/wave-core/src/lib/help/about/help-about.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-help-about', - templateUrl: './help-about.component.html', - styleUrls: ['./help-about.component.css'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpAboutComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/projects/wave-core/src/lib/help/account/help-account.component.css b/projects/wave-core/src/lib/help/account/help-account.component.css deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/help/account/help-account.component.html b/projects/wave-core/src/lib/help/account/help-account.component.html deleted file mode 100644 index e2857d5d..00000000 --- a/projects/wave-core/src/lib/help/account/help-account.component.html +++ /dev/null @@ -1,9 +0,0 @@ - - Account / Login -

There is currently no register page for obtaining a Vat account.

-

- If you are interested in obtaining an account please contact us at - vat [at] mathematik.uni-marburg.de. -

-

To log in click the button in the top-right, and select the type of account

-
diff --git a/projects/wave-core/src/lib/help/account/help-account.component.ts b/projects/wave-core/src/lib/help/account/help-account.component.ts deleted file mode 100644 index 08349fee..00000000 --- a/projects/wave-core/src/lib/help/account/help-account.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-help-account', - templateUrl: './help-account.component.html', - styleUrls: ['./help-account.component.css'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpAccountComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/projects/wave-core/src/lib/help/data/help-data.component.css b/projects/wave-core/src/lib/help/data/help-data.component.css deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/help/data/help-data.component.html b/projects/wave-core/src/lib/help/data/help-data.component.html deleted file mode 100644 index 13cf7863..00000000 --- a/projects/wave-core/src/lib/help/data/help-data.component.html +++ /dev/null @@ -1,13 +0,0 @@ - - Add Data -

- The Vat system supports two very different types of data: raster and vector data. Rasters consist of many - pixels, and each pixel contains a value for the particular location, e.g. the mean temperature. Vector data are collections of - features with attributes, e.g. a set of occurrences of pumas and the time of the observation -

-

- Under Add Data you can select one of several environmental layers (rasters), occurrence data from - GBIF, data from GFBio archives in ABCD format and your own custom data -

-

Each data set is added to the map as a layer which you can further process with operators.

-
diff --git a/projects/wave-core/src/lib/help/data/help-data.component.ts b/projects/wave-core/src/lib/help/data/help-data.component.ts deleted file mode 100644 index f1aea813..00000000 --- a/projects/wave-core/src/lib/help/data/help-data.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-help-data', - templateUrl: './help-data.component.html', - styleUrls: ['./help-data.component.css'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpDataComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/projects/wave-core/src/lib/help/export/help-export.component.css b/projects/wave-core/src/lib/help/export/help-export.component.css deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/help/export/help-export.component.html b/projects/wave-core/src/lib/help/export/help-export.component.html deleted file mode 100644 index 5b23f182..00000000 --- a/projects/wave-core/src/lib/help/export/help-export.component.html +++ /dev/null @@ -1,7 +0,0 @@ - - Data Export -

- The result of computations can be exported by clicking the Export button in a layer's context menu. After selecting the - output format, a ZIP file is generated that bundles the actual data with all citations and the workflow itself -

-
diff --git a/projects/wave-core/src/lib/help/export/help-export.component.ts b/projects/wave-core/src/lib/help/export/help-export.component.ts deleted file mode 100644 index 83f71668..00000000 --- a/projects/wave-core/src/lib/help/export/help-export.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-help-export', - templateUrl: './help-export.component.html', - styleUrls: ['./help-export.component.css'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpExportComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/projects/wave-core/src/lib/help/feedback/help-feedback.component.html b/projects/wave-core/src/lib/help/feedback/help-feedback.component.html deleted file mode 100644 index e199ee33..00000000 --- a/projects/wave-core/src/lib/help/feedback/help-feedback.component.html +++ /dev/null @@ -1,28 +0,0 @@ - - Contact Us / Feedback - - diff --git a/projects/wave-core/src/lib/help/feedback/help-feedback.component.scss b/projects/wave-core/src/lib/help/feedback/help-feedback.component.scss deleted file mode 100644 index 9c86df04..00000000 --- a/projects/wave-core/src/lib/help/feedback/help-feedback.component.scss +++ /dev/null @@ -1,8 +0,0 @@ -.feedback-container { - display: flex; - flex-direction: column; -} - -.feedback-container > * { - width: 100%; -} diff --git a/projects/wave-core/src/lib/help/feedback/help-feedback.component.ts b/projects/wave-core/src/lib/help/feedback/help-feedback.component.ts deleted file mode 100644 index d3d8e4de..00000000 --- a/projects/wave-core/src/lib/help/feedback/help-feedback.component.ts +++ /dev/null @@ -1,41 +0,0 @@ -import {Component, OnInit} from '@angular/core'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; - -/** @title Feedback component */ -@Component({ - selector: 'wave-help-feedback', - templateUrl: 'help-feedback.component.html', - styleUrls: ['help-feedback.component.scss'], -}) -export class HelpFeedbackComponent implements OnInit { - form: FormGroup; - - constructor(private formBuilder: FormBuilder) {} - - ngOnInit() { - this.form = this.formBuilder.group({ - requestType: ['Feedback', Validators.required], - name: ['', [Validators.required, Validators.minLength(1)]], - email: ['', [Validators.required, Validators.email]], - topic: ['', [Validators.required, Validators.minLength(1)]], - text: ['', [Validators.required, Validators.minLength(1)]], - }); - - setTimeout(() => this.form.updateValueAndValidity({emitEvent: true})); - } - - send() { - const mailTo = 'vat@mathematik.uni-marburg.de'; - const subject = `[${this.form.controls['requestType'].value}] ${this.form.controls['topic'].value}`; - const message = ` - Reply To: ${this.form.controls['email'].value} - \n\n - ~~~~~~~~~~ - \n\n - ${this.form.controls['text'].value} - `.trim(); - - // TODO: replace with web service call - window.location.href = `mailto:${mailTo}?subject=${subject}&body=${message}`; - } -} diff --git a/projects/wave-core/src/lib/help/general-information/help-general-information.component.css b/projects/wave-core/src/lib/help/general-information/help-general-information.component.css deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/help/general-information/help-general-information.component.html b/projects/wave-core/src/lib/help/general-information/help-general-information.component.html deleted file mode 100644 index 40c97822..00000000 --- a/projects/wave-core/src/lib/help/general-information/help-general-information.component.html +++ /dev/null @@ -1,13 +0,0 @@ - - General Information -

- The Vat system allows users to explore biodiversity data by selecting one of several data sources and - processing them with our built-in operators. -

-

Guest users can already try the system. The main features for registered users are:

-
    -
  • Saving work
  • -
  • Uploading custom data
  • -
  • Soon: Sharing results with other users
  • -
-
diff --git a/projects/wave-core/src/lib/help/general-information/help-general-information.component.ts b/projects/wave-core/src/lib/help/general-information/help-general-information.component.ts deleted file mode 100644 index 69dc960d..00000000 --- a/projects/wave-core/src/lib/help/general-information/help-general-information.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-help-general-information', - templateUrl: './help-general-information.component.html', - styleUrls: ['./help-general-information.component.css'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpGeneralInformationComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/projects/wave-core/src/lib/help/help.component.scss b/projects/wave-core/src/lib/help/help.component.scss deleted file mode 100644 index e9d76ff5..00000000 --- a/projects/wave-core/src/lib/help/help.component.scss +++ /dev/null @@ -1,14 +0,0 @@ -:host ::ng-deep mat-expansion-panel { - p { - text-align: justify; - } - - .vat { - font-variant: small-caps; - } - - img.extern { - height: 40px; - padding-right: 5px; - } -} diff --git a/projects/wave-core/src/lib/help/help.component.ts b/projects/wave-core/src/lib/help/help.component.ts deleted file mode 100644 index d68c9749..00000000 --- a/projects/wave-core/src/lib/help/help.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {Component, ChangeDetectionStrategy, OnInit} from '@angular/core'; - -@Component({ - selector: 'wave-help', - templateUrl: 'help.html', - styleUrls: ['./help.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpComponent implements OnInit { - ngOnInit() {} -} diff --git a/projects/wave-core/src/lib/help/help.html b/projects/wave-core/src/lib/help/help.html deleted file mode 100644 index 9cf39119..00000000 --- a/projects/wave-core/src/lib/help/help.html +++ /dev/null @@ -1,14 +0,0 @@ -Help - - - - - - - - - - - - - diff --git a/projects/wave-core/src/lib/help/lineage/help-lineage.component.css b/projects/wave-core/src/lib/help/lineage/help-lineage.component.css deleted file mode 100644 index 66e1654d..00000000 --- a/projects/wave-core/src/lib/help/lineage/help-lineage.component.css +++ /dev/null @@ -1,3 +0,0 @@ -img { - max-width: 100%; -} diff --git a/projects/wave-core/src/lib/help/lineage/help-lineage.component.html b/projects/wave-core/src/lib/help/lineage/help-lineage.component.html deleted file mode 100644 index 30dfdd49..00000000 --- a/projects/wave-core/src/lib/help/lineage/help-lineage.component.html +++ /dev/null @@ -1,9 +0,0 @@ - - Lineage Tracking - Lineage -

- The Vat system's goal is to support interactive data exploration by tracking the data processing - automatically in the background. You can view the complete processing workflow for individual layers by selecting Lineage in - the layer context menu and the lineage for all layers by clicking on the context menu of the layer list in the top left. -

-
diff --git a/projects/wave-core/src/lib/help/lineage/help-lineage.component.ts b/projects/wave-core/src/lib/help/lineage/help-lineage.component.ts deleted file mode 100644 index ce75402c..00000000 --- a/projects/wave-core/src/lib/help/lineage/help-lineage.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-help-lineage', - templateUrl: './help-lineage.component.html', - styleUrls: ['./help-lineage.component.css'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpLineageComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/projects/wave-core/src/lib/help/operators/help-operators.component.css b/projects/wave-core/src/lib/help/operators/help-operators.component.css deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/help/operators/help-operators.component.html b/projects/wave-core/src/lib/help/operators/help-operators.component.html deleted file mode 100644 index 006be8e2..00000000 --- a/projects/wave-core/src/lib/help/operators/help-operators.component.html +++ /dev/null @@ -1,59 +0,0 @@ - - Operators -

Operators allow you to process the layers that were previously added to the map. Our current operators are:

-
    -
  • - Mixed -
      -
    • - Raster Value Extraction -
        -
      • - Select a vector layer and one or more raster layers. The raster values at the location of the features are - attached as new attributes. E.g. you can add an elevation attribute to pumas, containing the elevation at - the puma's observed location -
      • -
      -
    • -
    -
  • - -
  • - Plots -
      -
    • Histogram: Plot a histogram of the data distribution of a raster or vector layer.
    • -
    -
  • -
  • - Raster -
      -
    • - Expression -
        -
      • Evaluate an expression on the pixel values of the input rasters
      • -
      -
    • -
    -
  • -
  • - Vectors -
      -
    • - Numeric Attribute Filter -
        -
      • Perform a range filter on a numeric attribute of a feature collection
      • -
      -
    • -
    • - Point in Polygon Filter -
        -
      • - Select a point and a polygon layer and create a new layer containing only those points that are contained in at - least one polygon. -
      • -
      -
    • -
    -
  • -
-
diff --git a/projects/wave-core/src/lib/help/operators/help-operators.component.ts b/projects/wave-core/src/lib/help/operators/help-operators.component.ts deleted file mode 100644 index c51b9bc1..00000000 --- a/projects/wave-core/src/lib/help/operators/help-operators.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-help-operators', - templateUrl: './help-operators.component.html', - styleUrls: ['./help-operators.component.css'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpOperatorsComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/projects/wave-core/src/lib/help/overview/help-overview.component.css b/projects/wave-core/src/lib/help/overview/help-overview.component.css deleted file mode 100644 index b4b5ef32..00000000 --- a/projects/wave-core/src/lib/help/overview/help-overview.component.css +++ /dev/null @@ -1,3 +0,0 @@ -img { - width: 100%; -} diff --git a/projects/wave-core/src/lib/help/overview/help-overview.component.html b/projects/wave-core/src/lib/help/overview/help-overview.component.html deleted file mode 100644 index 809da0d2..00000000 --- a/projects/wave-core/src/lib/help/overview/help-overview.component.html +++ /dev/null @@ -1,68 +0,0 @@ - - Overview of the User Interface - - User Interface Overview -
- Click to enhance -
-

The user interface consists of the following main parts:

-
    -
  • - Map (center) -
      -
    • Here, all data is visualized.
    • -
    -
  • -
  • - Layer list (left) -
      -
    • All layers that were added to the map are listed.
    • -
    • You can change the order of the layers via drag and drop.
    • -
    • Additionally, legends for the layers are shown.
    • -
    • A layer can be selected as active for the data table and feature selection in the map.
    • -
    -
  • -
  • - Data table & Citation (bottom) -
      -
    • Data table: Here, information about individual items in the layer are shown.
    • -
    • Citations: Inspect the citation information of all data sets that were involved in creating the layer.
    • -
    -
  • -
  • - Sidebar (right) -
      -
    • - Here, the core functionality of the system is available. Clicking one of the buttons on the right hand side opens the - sidebar. -
    • -
    • Login: Login to the system to use more advanced features not available to guests.
    • -
    • - Add data: Select data from one of the following categories -
        -
      • Environmental data
      • -
      • Species distribution
      • -
      • Custom (uploaded) data
      • -
      -
    • -
    • Operators: Perform an operation on one or multiple layers previously added to the map.
    • -
    • Time: Select the reference time for the current project (cf. Time)
    • -
    • Plots: Inspect plots like graphs and histograms
    • -
    • - Workspace: Configure your workspace -
        -
      • Load/Save project
      • -
      • Change the currently active projection
      • -
      -
    • -
    • Help: Open this help functionality
    • -
    -
  • -
  • - Time (top) -
      -
    • Step through the time. For more detailed information see time
    • -
    -
  • -
-
diff --git a/projects/wave-core/src/lib/help/overview/help-overview.component.ts b/projects/wave-core/src/lib/help/overview/help-overview.component.ts deleted file mode 100644 index eb138adc..00000000 --- a/projects/wave-core/src/lib/help/overview/help-overview.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-help-overview', - templateUrl: './help-overview.component.html', - styleUrls: ['./help-overview.component.css'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpOverviewComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/projects/wave-core/src/lib/help/quick-demo/help-quick-demo.component.css b/projects/wave-core/src/lib/help/quick-demo/help-quick-demo.component.css deleted file mode 100644 index aecd1361..00000000 --- a/projects/wave-core/src/lib/help/quick-demo/help-quick-demo.component.css +++ /dev/null @@ -1,4 +0,0 @@ -iframe { - width: 100%; - border: none; -} diff --git a/projects/wave-core/src/lib/help/quick-demo/help-quick-demo.component.html b/projects/wave-core/src/lib/help/quick-demo/help-quick-demo.component.html deleted file mode 100644 index 7d6ec2f7..00000000 --- a/projects/wave-core/src/lib/help/quick-demo/help-quick-demo.component.html +++ /dev/null @@ -1,4 +0,0 @@ - - Quick Demo - - diff --git a/projects/wave-core/src/lib/help/quick-demo/help-quick-demo.component.ts b/projects/wave-core/src/lib/help/quick-demo/help-quick-demo.component.ts deleted file mode 100644 index e23ee4de..00000000 --- a/projects/wave-core/src/lib/help/quick-demo/help-quick-demo.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; - -@Component({ - selector: 'wave-help-quick-demo', - templateUrl: './help-quick-demo.component.html', - styleUrls: ['./help-quick-demo.component.css'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HelpQuickDemoComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/projects/wave-core/src/lib/layers/dialogs/layer-export/layer-export.component.html b/projects/wave-core/src/lib/layers/dialogs/layer-export/layer-export.component.html deleted file mode 100644 index b00d1a9c..00000000 --- a/projects/wave-core/src/lib/layers/dialogs/layer-export/layer-export.component.html +++ /dev/null @@ -1,36 +0,0 @@ -Export: {{ layer.name }} -
-
- - - -
-
- - - - - - -
-
- - - {{ type }} - - - - - {{ type }} - - -
-
- - - JSON - - -
- -
diff --git a/projects/wave-core/src/lib/layers/dialogs/layer-export/layer-export.component.scss b/projects/wave-core/src/lib/layers/dialogs/layer-export/layer-export.component.scss deleted file mode 100644 index 3389205f..00000000 --- a/projects/wave-core/src/lib/layers/dialogs/layer-export/layer-export.component.scss +++ /dev/null @@ -1,11 +0,0 @@ -div:first-child { - margin-top: 1rem; -} - -div:not(:first-child) { - margin-bottom: 1rem; -} - -mat-select { - margin-bottom: 1rem; -} diff --git a/projects/wave-core/src/lib/layers/dialogs/layer-export/layer-export.component.ts b/projects/wave-core/src/lib/layers/dialogs/layer-export/layer-export.component.ts deleted file mode 100644 index b9736f58..00000000 --- a/projects/wave-core/src/lib/layers/dialogs/layer-export/layer-export.component.ts +++ /dev/null @@ -1,113 +0,0 @@ -import {first} from 'rxjs/operators'; -import {Subscription} from 'rxjs'; - -import {Component, OnInit, ChangeDetectionStrategy, AfterViewInit, OnDestroy, Inject} from '@angular/core'; -import {WFSOutputFormats} from '../../../queries/output-formats/wfs-output-format.model'; -import {WCSOutputFormats} from '../../../queries/output-formats/wcs-output-format.model'; -import {FormGroup, FormBuilder, Validators} from '@angular/forms'; -import {Layer} from '../../layer.model'; -import {AbstractSymbology} from '../../symbology/symbology.model'; -import {MAT_DIALOG_DATA} from '@angular/material/dialog'; -import {ResultTypes} from '../../../operators/result-type.model'; -import {MappingQueryService} from '../../../queries/mapping-query.service'; -import {ProjectService} from '../../../project/project.service'; - -interface LayerExportComponentConfig { - layer: Layer; -} - -@Component({ - selector: 'wave-layer-export', - templateUrl: './layer-export.component.html', - styleUrls: ['./layer-export.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LayerExportComponent implements OnInit, AfterViewInit, OnDestroy { - // make available - WFSOutputFormats = WFSOutputFormats; - WCSOutputFormats = WCSOutputFormats; - // - - form: FormGroup; - - layer: Layer; - - isRaster: boolean; - isVector: boolean; - - private subscriptions: Array = []; - - constructor( - private formBuilder: FormBuilder, - private mappingQueryService: MappingQueryService, - private projectService: ProjectService, - @Inject(MAT_DIALOG_DATA) private config: LayerExportComponentConfig, - ) {} - - ngOnInit() { - // const config = this.dialogRef.config as LayerExportComponentConfig; - this.layer = this.config.layer; - - this.isRaster = this.layer.operator.resultType === ResultTypes.RASTER; - this.isVector = ResultTypes.VECTOR_TYPES.indexOf(this.layer.operator.resultType) >= 0; - - if (this.isRaster && this.isVector) { - throw Error('The layer must be of type raster OR vector'); - } - - this.form = this.formBuilder.group({ - outputName: [{value: 'export', disabled: true}, Validators.required], - dataOutputFormat: [undefined, Validators.required], - citationFormat: ['json', Validators.required], - rasterResolution: this.formBuilder.group({ - width: [1024, Validators.required], - height: [{value: 1024, disabled: true}, Validators.required], - }), - }); - - this.subscriptions.push( - (this.form.controls['rasterResolution'] as FormGroup).controls['width'].valueChanges.subscribe((width) => { - (this.form.controls['rasterResolution'] as FormGroup).controls['height'].setValue(width); - }), - ); - } - - ngAfterViewInit() { - setTimeout(() => this.form.updateValueAndValidity()); - } - - ngOnDestroy() { - this.subscriptions.forEach((subscription) => subscription.unsubscribe()); - } - - download() { - this.projectService - .getProjectStream() - .pipe(first()) - .subscribe((project) => { - if (this.isVector) { - location.href = this.mappingQueryService.getWFSQueryUrl({ - operator: this.layer.operator, - outputFormat: this.form.controls['dataOutputFormat'].value, - time: project.time, - projection: project.projection, - }); - } - - if (this.isRaster) { - const rasterResolution = this.form.controls['rasterResolution'] as FormGroup; - - location.href = this.mappingQueryService.getWCSQueryUrl({ - operator: this.layer.operator, - outputFormat: this.form.controls['dataOutputFormat'].value, - size: { - x: rasterResolution.controls['width'].value, - y: rasterResolution.controls['height'].value, - }, - time: project.time, - projection: project.projection, - }); - } - }); - } -} diff --git a/projects/wave-core/src/lib/layers/dialogs/layer-share/layer-share.component.html b/projects/wave-core/src/lib/layers/dialogs/layer-share/layer-share.component.html deleted file mode 100644 index 2c08548a..00000000 --- a/projects/wave-core/src/lib/layers/dialogs/layer-share/layer-share.component.html +++ /dev/null @@ -1,10 +0,0 @@ -Share: {{ layer.name }} -

Copy this link to share the selected layer with others.

-
- - - - -
diff --git a/projects/wave-core/src/lib/layers/dialogs/layer-share/layer-share.component.scss b/projects/wave-core/src/lib/layers/dialogs/layer-share/layer-share.component.scss deleted file mode 100644 index 3b0c351d..00000000 --- a/projects/wave-core/src/lib/layers/dialogs/layer-share/layer-share.component.scss +++ /dev/null @@ -1,7 +0,0 @@ -div { - margin-top: 1em; -} - -input { - color: var(--wave-foreground-text-color, black) !important; -} diff --git a/projects/wave-core/src/lib/layers/dialogs/layer-share/layer-share.component.ts b/projects/wave-core/src/lib/layers/dialogs/layer-share/layer-share.component.ts deleted file mode 100644 index 6989268c..00000000 --- a/projects/wave-core/src/lib/layers/dialogs/layer-share/layer-share.component.ts +++ /dev/null @@ -1,43 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy, Inject, ViewChild, ElementRef} from '@angular/core'; -import {Layer} from '../../layer.model'; -import {AbstractSymbology} from '../../symbology/symbology.model'; -import {MAT_DIALOG_DATA} from '@angular/material/dialog'; - -interface LayerShareComponentConfig { - layer: Layer; -} - -@Component({ - selector: 'wave-layer-share-dialog', - templateUrl: './layer-share.component.html', - styleUrls: ['./layer-share.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LayerShareComponent implements OnInit { - layer: Layer; - link: string; - - @ViewChild('linkInput', {static: true}) - private linkInput: ElementRef; - - constructor(@Inject(MAT_DIALOG_DATA) private config: LayerShareComponentConfig) {} - - ngOnInit() { - this.layer = this.config.layer; - - const layerJSON = JSON.stringify(this.layer.toDict()); - - this.link = `${window.location.origin}${window.location.pathname}#/?workflow=${encodeURI(layerJSON)}`; - } - - copyLink() { - const disabled = this.linkInput.nativeElement.disabled; - this.linkInput.nativeElement.disabled = false; - - this.linkInput.nativeElement.focus(); - this.linkInput.nativeElement.select(); - document.execCommand('copy'); - - this.linkInput.nativeElement.disabled = disabled; - } -} diff --git a/projects/wave-core/src/lib/layers/dialogs/rename-layer.component.ts b/projects/wave-core/src/lib/layers/dialogs/rename-layer.component.ts deleted file mode 100644 index 3dcc91b4..00000000 --- a/projects/wave-core/src/lib/layers/dialogs/rename-layer.component.ts +++ /dev/null @@ -1,66 +0,0 @@ -import {Component, ChangeDetectionStrategy, OnInit, Inject} from '@angular/core'; - -import {Layer} from '../layer.model'; -import {AbstractSymbology} from '../symbology/symbology.model'; -import {FormGroup, FormBuilder, Validators} from '@angular/forms'; -import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; -import {ProjectService} from '../../project/project.service'; - -@Component({ - selector: 'wave-rename-layer-dialog', - template: ` - Rename the Current Layer -
- - - - - - - - -
- `, - styles: [ - ` - form { - padding-top: 16px; - } - mat-form-field { - width: 100%; - } - `, - ], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class RenameLayerComponent implements OnInit { - form: FormGroup; - - private layer: Layer; - - constructor( - private projectService: ProjectService, - private formBuilder: FormBuilder, - private dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) private config: {layer?: Layer}, - ) {} - - ngOnInit(): void { - // this.layer = (this.dialogRef.config as {layer?: Layer}).layer; - this.layer = this.config.layer; - this.form = this.formBuilder.group({ - layerName: [this.layer.name, Validators.required], - }); - } - - /** - * Save the layer name and close the dialog. - */ - save(event: any) { - const layerName = this.form.controls['layerName'].value; - if (layerName !== this.layer.name) { - this.projectService.changeLayer(this.layer, {name: layerName}); - } - this.dialogRef.close(); - } -} diff --git a/projects/wave-core/src/lib/layers/layer-icons/line-icon/line-icon.component.scss b/projects/wave-core/src/lib/layers/layer-icons/line-icon/line-icon.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/layers/layer-icons/line-icon/line-icon.component.svg b/projects/wave-core/src/lib/layers/layer-icons/line-icon/line-icon.component.svg deleted file mode 100644 index f9bffd37..00000000 --- a/projects/wave-core/src/lib/layers/layer-icons/line-icon/line-icon.component.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/projects/wave-core/src/lib/layers/layer-icons/line-icon/line-icon.component.ts b/projects/wave-core/src/lib/layers/layer-icons/line-icon/line-icon.component.ts deleted file mode 100644 index 57dad06e..00000000 --- a/projects/wave-core/src/lib/layers/layer-icons/line-icon/line-icon.component.ts +++ /dev/null @@ -1,50 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy, Input, SimpleChanges, OnChanges} from '@angular/core'; -import {StrokeDashStyle} from '../../symbology/symbology.model'; -import {BLACK, Color} from '../../../colors/color'; - -/** - * A simple interface to specify the style of a line icon. - */ -export interface LineIconStyle { - strokeWidth: number; - strokeDashStyle: StrokeDashStyle; - strokeRGBA: Color; -} - -/** - * The line icon component - */ -@Component({ - selector: 'wave-line-icon', - templateUrl: './line-icon.component.svg', - styleUrls: ['./line-icon.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LineIconComponent implements OnInit, OnChanges { - // the style to use for the icon - @Input() - iconStyle: LineIconStyle; - strokeWidth = 2; - strokeDashArray: Array = []; - strokeColor = BLACK.rgbaCssString(); - - constructor() {} - - ngOnInit(): void { - if (this.iconStyle) { - this.updateStyle(); - } - } - - ngOnChanges(changes: SimpleChanges): void { - if (changes) { - this.updateStyle(); - } - } - - private updateStyle() { - this.strokeWidth = this.iconStyle.strokeWidth; - this.strokeDashArray = this.iconStyle.strokeDashStyle ? this.iconStyle.strokeDashStyle : []; - this.strokeColor = this.iconStyle.strokeRGBA.rgbaCssString(); - } -} diff --git a/projects/wave-core/src/lib/layers/layer-icons/point-icon/point-icon.component.scss b/projects/wave-core/src/lib/layers/layer-icons/point-icon/point-icon.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/layers/layer-icons/point-icon/point-icon.component.svg b/projects/wave-core/src/lib/layers/layer-icons/point-icon/point-icon.component.svg deleted file mode 100644 index 19e42c5f..00000000 --- a/projects/wave-core/src/lib/layers/layer-icons/point-icon/point-icon.component.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/projects/wave-core/src/lib/layers/layer-icons/point-icon/point-icon.component.ts b/projects/wave-core/src/lib/layers/layer-icons/point-icon/point-icon.component.ts deleted file mode 100644 index 0943d892..00000000 --- a/projects/wave-core/src/lib/layers/layer-icons/point-icon/point-icon.component.ts +++ /dev/null @@ -1,53 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy, Input, OnChanges, SimpleChanges} from '@angular/core'; -import {StrokeDashStyle} from '../../symbology/symbology.model'; -import {BLACK, Color, WHITE} from '../../../colors/color'; - -/** - * A simple interface to specify the style of a point icon - */ -export interface PointIconStyle { - strokeWidth: number; - strokeDashStyle: StrokeDashStyle; - strokeRGBA: Color; - fillRGBA: Color; -} - -/** - * The point icon component - */ -@Component({ - selector: 'wave-point-icon', - templateUrl: './point-icon.component.svg', - styleUrls: ['./point-icon.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class PointIconComponent implements OnInit, OnChanges { - // the style to use for the icon - @Input() - iconStyle: PointIconStyle; - strokeWidth = 2; - strokeDashArray: Array = []; - strokeColor = BLACK.rgbaCssString(); - fillColor = WHITE.rgbaCssString(); - - constructor() {} - - ngOnInit(): void { - if (this.iconStyle) { - this.updateStyle(); - } - } - - ngOnChanges(changes: SimpleChanges): void { - if (changes) { - this.updateStyle(); - } - } - - private updateStyle() { - this.strokeWidth = this.iconStyle.strokeWidth; - this.strokeDashArray = this.iconStyle.strokeDashStyle ? this.iconStyle.strokeDashStyle : []; - this.strokeColor = this.iconStyle.strokeRGBA.rgbaCssString(); - this.fillColor = this.iconStyle.fillRGBA.rgbaCssString(); - } -} diff --git a/projects/wave-core/src/lib/layers/layer-icons/polygon-icon/polygon-icon.component.scss b/projects/wave-core/src/lib/layers/layer-icons/polygon-icon/polygon-icon.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/layers/layer-icons/polygon-icon/polygon-icon.component.svg b/projects/wave-core/src/lib/layers/layer-icons/polygon-icon/polygon-icon.component.svg deleted file mode 100644 index 426498e4..00000000 --- a/projects/wave-core/src/lib/layers/layer-icons/polygon-icon/polygon-icon.component.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/projects/wave-core/src/lib/layers/layer-icons/polygon-icon/polygon-icon.component.ts b/projects/wave-core/src/lib/layers/layer-icons/polygon-icon/polygon-icon.component.ts deleted file mode 100644 index 133d2dbe..00000000 --- a/projects/wave-core/src/lib/layers/layer-icons/polygon-icon/polygon-icon.component.ts +++ /dev/null @@ -1,53 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy, Input, SimpleChanges, OnChanges} from '@angular/core'; -import {StrokeDashStyle} from '../../symbology/symbology.model'; -import {BLACK, Color, WHITE} from '../../../colors/color'; - -/** - * A simple interface to specify the style of a polygon icon - */ -export interface PolygonIconStyle { - strokeWidth: number; - strokeDashStyle: StrokeDashStyle; - strokeRGBA: Color; - fillRGBA: Color; -} - -/** - * The polygon icon component - */ -@Component({ - selector: 'wave-polygon-icon', - templateUrl: './polygon-icon.component.svg', - styleUrls: ['./polygon-icon.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class PolygonIconComponent implements OnInit, OnChanges { - // the style to use for the icon - @Input() - iconStyle: PolygonIconStyle; - strokeWidth = 2; - strokeDashArray: Array = []; - strokeColor = BLACK.rgbaCssString(); - fillColor = WHITE.rgbaCssString(); - - constructor() {} - - ngOnInit(): void { - if (this.iconStyle) { - this.updateStyle(); - } - } - - ngOnChanges(changes: SimpleChanges): void { - if (changes) { - this.updateStyle(); - } - } - - private updateStyle() { - this.strokeWidth = this.iconStyle.strokeWidth; - this.strokeDashArray = this.iconStyle.strokeDashStyle ? this.iconStyle.strokeDashStyle : []; - this.strokeColor = this.iconStyle.strokeRGBA.rgbaCssString(); - this.fillColor = this.iconStyle.fillRGBA.rgbaCssString(); - } -} diff --git a/projects/wave-core/src/lib/layers/layer-icons/raster-icon/raster-icon.component.scss b/projects/wave-core/src/lib/layers/layer-icons/raster-icon/raster-icon.component.scss deleted file mode 100644 index 6aeb9710..00000000 --- a/projects/wave-core/src/lib/layers/layer-icons/raster-icon/raster-icon.component.scss +++ /dev/null @@ -1,6 +0,0 @@ -svg { - rect { - //stroke: rgba(0,0,0,0.5); - //stroke-width: 1px; - } -} diff --git a/projects/wave-core/src/lib/layers/layer-icons/raster-icon/raster-icon.component.svg b/projects/wave-core/src/lib/layers/layer-icons/raster-icon/raster-icon.component.svg deleted file mode 100644 index dfef2656..00000000 --- a/projects/wave-core/src/lib/layers/layer-icons/raster-icon/raster-icon.component.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - diff --git a/projects/wave-core/src/lib/layers/layer-icons/raster-icon/raster-icon.component.ts b/projects/wave-core/src/lib/layers/layer-icons/raster-icon/raster-icon.component.ts deleted file mode 100644 index 27e8d30b..00000000 --- a/projects/wave-core/src/lib/layers/layer-icons/raster-icon/raster-icon.component.ts +++ /dev/null @@ -1,90 +0,0 @@ -import {ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChange} from '@angular/core'; -import {IColorizerData} from '../../../colors/colorizer-data.model'; -import {Color} from '../../../colors/color'; - -/** - * a simple interface to model a cell in the raster icon - */ -interface Cell { - xStart: number; - yStart: number; - xSize: number; - ySize: number; - colorString: string; -} - -/** - * The raster icon component displays colored cells to visualize the raster style - */ -@Component({ - selector: 'wave-raster-icon', - templateUrl: './raster-icon.component.svg', - styleUrls: ['./raster-icon.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class RasterIconComponent implements OnInit, OnChanges { - // number of cells in x and y direction - @Input() xCells: number; - @Input() yCells: number; - // the raster style used to color the icon - @Input() colorizer: IColorizerData; - - /** - * the array of generated (colored and positioned) cells. - */ - cells: Array; - /** - * This is the number of pixels used for the icon - */ - cellSpace = 24; - - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { - this.generateCells(this.xCells, this.yCells); - } - - ngOnInit() { - this.generateCells(this.xCells, this.yCells); - } - - /** - * generates an array of cell descriptors which are used by the template - */ - generateCells(xCells: number, yCells: number) { - this.cells = new Array(xCells * yCells); - for (let y = 0; y < this.yCells; y++) { - for (let x = 0; x < this.xCells; x++) { - const idx = this.xCells * y + x; - this.cells[idx] = { - xStart: (x * this.cellSpace) / this.xCells, - yStart: (y * this.cellSpace) / this.yCells, - xSize: this.cellSpace / this.xCells, - ySize: this.cellSpace / this.yCells, - colorString: Color.rgbaToCssString(this.cellColor(x, y)), - }; - } - } - } - - private cellColor(x: number, y: number): Color { - const validSymbology = this.colorizer && this.colorizer.breakpoints && this.colorizer.breakpoints.length > 0; - if (!validSymbology) { - return Color.fromRgbaLike('ff000000'); - } - - const numberOfCells = this.xCells * this.yCells; - const numberOfColors = this.colorizer.breakpoints.length; - const isGradient = this.colorizer.type === 'gradient' || this.colorizer.type === 'logarithmic'; - - const scale = isGradient ? numberOfColors / (this.xCells + this.yCells - 1) : numberOfColors / numberOfCells; - - const idx = y * this.xCells + x; - let colorIdx = 0; - if (numberOfColors === 2) { - colorIdx = y % 2 === 0 ? x % 2 : (x + 1) % 2; - } else { - const uidx = isGradient ? this.xCells - 1 - x + y : idx; - colorIdx = Math.trunc(uidx * scale) % numberOfColors; - } - return Color.fromRgbaLike(this.colorizer.breakpoints[colorIdx].rgba); - } -} diff --git a/projects/wave-core/src/lib/layers/layer-list/layer-list.component.html b/projects/wave-core/src/lib/layers/layer-list/layer-list.component.html deleted file mode 100644 index d0c12183..00000000 --- a/projects/wave-core/src/lib/layers/layer-list/layer-list.component.html +++ /dev/null @@ -1,253 +0,0 @@ -
- - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- -
-
-
- - - - - - - - - - - - - - -
-
- - - - -
- {{ layer.name }} -
- - -
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - -
- - -
-
- -
-
-
diff --git a/projects/wave-core/src/lib/layers/layer-list/layer-list.component.scss b/projects/wave-core/src/lib/layers/layer-list/layer-list.component.scss deleted file mode 100644 index d4d2cbe0..00000000 --- a/projects/wave-core/src/lib/layers/layer-list/layer-list.component.scss +++ /dev/null @@ -1,176 +0,0 @@ -.container { - max-height: inherit; - height: inherit; -} - -.layer-list { - max-height: inherit; - overflow-y: auto; - max-width: 100%; - border: solid 1px #ccc; - min-height: 0; - display: block; - border-radius: 4px; -} - -.layer-list-element { - width: 100%; -} - -.layer-list-box { - font-size: 14px; - padding: 0; - min-height: 40px; - max-width: 100%; - border-bottom: solid 1px #ccc; - color: rgba(0, 0, 0, 0.87); - display: flex; - flex-direction: row; - align-items: flex-start; - justify-content: space-between; - box-sizing: border-box; - background-color: var(--wave-background-color, white); -} - -.cdk-drag-preview { - box-sizing: border-box; - border-radius: 4px; - box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); -} - -.layer-list-element-custom-placeholder { - background-color: #ccc; - border: dotted 3px #999; - min-height: 40px; - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.cdk-drag-animating { - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.layer-list-box:last-child { - border: none; -} - -.layer-list.cdk-drop-list-dragging .layer-list-box:not(.cdk-drag-placeholder) { - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -.layer-list-item-text { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -} - -.list-element-inner-container { - width: 100%; -} - -.no-layer { - width: 100%; -} - -::ng-deep .logo { - text-align: center; - - @media (max-width: 1480px) { - flex: 1; - } - - mat-icon { - vertical-align: sub; - } - - ::ng-deep svg { - border: 1px solid currentColor; - border-radius: 50%; - } - - .title { - font-family: 'Pacifico', cursive; - } - - .subtitle { - font-size: 0.75rem; - } -} - -.only-large { - @media (max-width: 1480px) { - display: none; - } -} - -.geobon-logo { - text-align: center; - - @media (max-width: 1480px) { - flex: 1; - } - - mat-icon { - vertical-align: baseline; - height: 1rem; - width: 80px; - } - - .title { - font-family: 'Pacifico', cursive; - } - - .subtitle { - font-size: 0.75rem; - } - - .up { - vertical-align: text-top; - } -} - -.grabbable { - cursor: grab; -} - -/* (Optional) Apply a "closed-hand" cursor during drag operation. */ -.grabbable:active { - cursor: grabbing; -} - -.small { - font-size: 0.8rem; -} - -.mat-toolbar { - padding: 0 !important; -} - -mat-toolbar div:first-child, -button { - width: 40px; -} - -mat-toolbar ::ng-deep mat-toolbar-row:first-child { - display: none !important; -} - -mat-progress-bar { - width: 100% !important; - height: 1px !important; - margin: 0 !important; - padding: 0 !important; -} - -mat-progress-bar { - height: 2px; -} - -.active-layer { - background-color: var(--wave-faded-accent-color, grey); -} - -.lineThrough { - background: url("data:image/svg+xml;utf8,") - no-repeat center center; - background-size: 100% 100%, auto; -} diff --git a/projects/wave-core/src/lib/layers/layer-list/layer-list.component.ts b/projects/wave-core/src/lib/layers/layer-list/layer-list.component.ts deleted file mode 100644 index 9c63afa2..00000000 --- a/projects/wave-core/src/lib/layers/layer-list/layer-list.component.ts +++ /dev/null @@ -1,141 +0,0 @@ -import {Observable, Subscription} from 'rxjs'; -import {Component, OnDestroy, Input, ChangeDetectionStrategy, ChangeDetectorRef} from '@angular/core'; -import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop'; -import {MatDialog} from '@angular/material/dialog'; -import {LayoutService, SidenavConfig} from '../../layout.service'; -import {SymbologyType, AbstractSymbology, VectorSymbology} from '../symbology/symbology.model'; -import {RenameLayerComponent} from '../dialogs/rename-layer.component'; -import {LoadingState} from '../../project/loading-state.model'; -import {LayerService} from '../layer.service'; -import {MapService} from '../../map/map.service'; -import {Layer} from '../layer.model'; -import {SourceOperatorListComponent} from '../../operators/dialogs/source-operator-list/source-operator-list.component'; -import {LineageGraphComponent} from '../../provenance/lineage-graph/lineage-graph.component'; -import {LayerExportComponent} from '../dialogs/layer-export/layer-export.component'; -import {ProjectService} from '../../project/project.service'; -import {LayerShareComponent} from '../dialogs/layer-share/layer-share.component'; -import {Config} from '../../config.service'; -import {SymbologyEditorComponent} from '../symbology/symbology-editor/symbology-editor.component'; -import {filter, map, startWith} from 'rxjs/operators'; - -/** - * The layer list component displays active layers, legends and other controlls. - */ -@Component({ - selector: 'wave-layer-list', - templateUrl: './layer-list.component.html', - styleUrls: ['./layer-list.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LayerListComponent implements OnDestroy { - /** - * The desired height of the list - */ - @Input() height: number; - - /** - * The empty list shows a button to trigger the generation of a first layer. - * This sidenav config is called to present a date listing or a similar dialog in the sidenav. - */ - @Input() addAFirstLayerSidenavConfig: SidenavConfig = {component: SourceOperatorListComponent}; - - /** - * sends if the layerlist should be visible - */ - readonly layerListVisibility$: Observable; - - /** - * sends if the map should be a grid (or else a single map) - */ - readonly mapIsGrid$: Observable; - - /** - * The list of layers displayed in the layer list - */ - layerList: Array> = []; - - // make ENUMS and classes visible in the template - readonly LayoutService = LayoutService; - readonly ST = SymbologyType; - readonly LoadingState = LoadingState; - readonly RenameLayerComponent = RenameLayerComponent; - readonly LineageGraphComponent = LineageGraphComponent; - readonly LayerExportComponent = LayerExportComponent; - readonly LayerShareComponent = LayerShareComponent; - readonly SourceOperatorListComponent = SourceOperatorListComponent; - readonly SymbologyEditorComponent = SymbologyEditorComponent; - - // inventory of used subscriptions - private subscriptions: Array = []; - - /** - * The component constructor. It injects angular and wave services. - */ - constructor( - public dialog: MatDialog, - public layoutService: LayoutService, - public projectService: ProjectService, - public layerService: LayerService, - public mapService: MapService, - public config: Config, - public changeDetectorRef: ChangeDetectorRef, - ) { - this.layerListVisibility$ = this.layoutService.getLayerListVisibilityStream(); - - this.subscriptions.push( - this.projectService.getLayerStream().subscribe((layerList) => { - if (layerList !== this.layerList) { - this.layerList = layerList; - } - this.changeDetectorRef.markForCheck(); - }), - ); - - this.mapIsGrid$ = this.mapService.isGrid$; - } - - ngOnDestroy() { - this.subscriptions.forEach((s) => s.unsubscribe()); - } - - /** - * the drop method is used by the dran and drop feature of the list - */ - drop(event: CdkDragDrop) { - moveItemInArray(this.layerList, event.previousIndex, event.currentIndex); - this.projectService.setLayers([...this.layerList]); // send a copy to keep the list private - } - - /** - * select a layer - */ - toggleLayer(layer: Layer) { - this.projectService.toggleSymbology(layer); - } - - /** - * method to get the symbology stream of a layer. This is used by the icons and legend components. - */ - getLayerSymbologyStream(layer: Layer): Observable { - return this.projectService.getLayerChangesStream(layer).pipe( - startWith(layer), - filter((lc) => !!lc.symbology), - map(() => layer.symbology), - ); - } - - /** - * helper method to cast AbstractSymbology to VectorSymbology - */ - vectorLayerCast(layer: Layer): Layer { - return layer as Layer; - } - - showChannelParameterSlider(layer: Layer): boolean { - return ( - layer.operator.operatorType.toString() === 'GDAL Source' && - !!layer.operator.operatorTypeParameterOptions && - layer.operator.operatorTypeParameterOptions.getParameterOption('channelConfig').hasTicks() - ); - } -} diff --git a/projects/wave-core/src/lib/layers/layer.model.ts b/projects/wave-core/src/lib/layers/layer.model.ts deleted file mode 100644 index 89637802..00000000 --- a/projects/wave-core/src/lib/layers/layer.model.ts +++ /dev/null @@ -1,341 +0,0 @@ -import {Observable, Observer} from 'rxjs'; - -import {Operator, OperatorDict} from '../operators/operator.model'; -import { - AbstractSymbology, - AbstractVectorSymbology, - MappingRasterSymbology, - AbstractRasterSymbology, - SymbologyDict, -} from './symbology/symbology.model'; -import {Provenance} from '../provenance/provenance.model'; -import {LoadingState} from '../project/loading-state.model'; -import {GeoJSON as OlFormatGeoJSON} from 'ol/format'; -import {Feature as OlFeature} from 'ol/Feature'; -import {ProjectionLike as OlProjectionLike} from 'ol/proj'; -import {Time, TimePoint} from '../time/time.model'; -import {Projection} from '../operators/projection.model'; - -export abstract class LayerData { - type: LayerType; - _time: Time; - _projection: Projection; - - protected constructor(type: LayerType, time: Time, projection: Projection) { - this.type = type; - this._projection = projection; - this._time = time; - } - - get time(): Time { - return this._time; - } - - get projection(): Projection { - return this._projection; - } - - abstract get data(): D; -} - -export class VectorData extends LayerData> { - _data: Array; - _extent: [number, number, number, number]; - - static olParse( - time: Time, - projection: Projection, - extent: [number, number, number, number], - source: Document | Node | any | string, - opt_options?: {dataProjection: OlProjectionLike; featureProjection: OlProjectionLike}, - ): VectorData { - return new VectorData(time, projection, new OlFormatGeoJSON().readFeatures(source, opt_options), extent); - } - - constructor(time: Time, projection: Projection, data: Array, extent: [number, number, number, number]) { - super('vector', time, projection); - this._data = data; - this._extent = extent; - this.fakeIds(); // FIXME: use real IDs ... - } - - get data(): Array { - return this._data; - } - - get extent(): [number, number, number, number] { - return this._extent; - } - - fakeIds() { - for (let localRowId = 0; localRowId < this.data.length; localRowId++) { - const feature = this.data[localRowId]; - if (feature.getId() === undefined) { - feature.setId(localRowId); - } - } - } -} - -export class RasterData extends LayerData { - _data: string; - - constructor(time: Time, projection: Projection, data: string) { - if (time.getEnd().isAfter(time.getStart())) { - time = new TimePoint(time.getStart()); - } - super('raster', time, projection); - this._data = data; - } - - get data(): string { - return this._data; - } -} - -export interface LayerChanges { - name?: string; - symbology?: S; - editSymbology?: boolean; - visible?: boolean; - expanded?: boolean; - operator?: Operator; -} - -export interface VectorLayerData { - data$: Observable>; - dataExtent$?: Observable<[number, number, number, number]>; - state$: Observable; - reload$: Observer; -} - -export interface LayerProvenance { - provenance$: Observable>; - state$: Observable; - reload$: Observer; -} - -interface LayerConfig { - name: string; - operator: Operator; - symbology: S; - expanded?: boolean; - visible?: boolean; - editSymbology?: boolean; -} - -interface VectorLayerConfig extends LayerConfig { - clustered?: boolean; -} - -interface RasterLayerConfig extends LayerConfig { - // eslint-disable-line @typescript-eslint/no-empty-interface -} - -type LayerType = 'raster' | 'vector'; - -interface LayerTypeOptionsDict { - // eslint-disable-line @typescript-eslint/no-empty-interface -} - -interface VectorLayerTypeOptionsDict extends LayerTypeOptionsDict { - clustered: boolean; -} - -/** - * Dictionary for serialization. - */ -export interface LayerDict { - name: string; - operator: OperatorDict; - symbology: SymbologyDict; - expanded: boolean; - visible: boolean; - editSymbology: boolean; - type: LayerType; - typeOptions?: LayerTypeOptionsDict; -} - -export abstract class Layer { - protected _name: string; - protected _expanded = false; - protected _visible = true; - protected _editSymbology = false; - protected _symbology: S; - protected _operator: Operator; - - /** - * Create the suitable layer type and initialize the callbacks. - */ - static fromDict(dict: LayerDict, operatorMap = new Map()): Layer { - switch (dict.type) { - case 'raster': - return RasterLayer.fromDict(dict, operatorMap); - case 'vector': - return VectorLayer.fromDict(dict, operatorMap); - default: - throw new Error('LayerService.createLayerFromDict: Unknown LayerType ->' + dict); - } - } - - protected constructor(config: LayerConfig) { - this._name = config.name; - this._operator = config.operator; - this._symbology = config.symbology; - if (config.expanded) { - this._expanded = config.expanded; - } - if (config.visible) { - this._visible = config.visible; - } - if (config.editSymbology) { - this._editSymbology = config.editSymbology; - } - } - - /** - * Changes the underlying data - * Do not use this method publically!!! - */ - _changeUnderlyingData(data: LayerChanges): LayerChanges { - const validChanges: LayerChanges = {}; - - if (data.name && data.name !== this._name) { - this._name = data.name; - validChanges.name = this._name; - } - - if (data.symbology !== undefined) { - this._symbology = data.symbology; - validChanges.symbology = this._symbology; - } - - if (data.visible !== undefined && data.visible !== this._visible) { - this._visible = data.visible; - validChanges.visible = this._visible; - } - - if (data.expanded !== undefined && data.expanded !== this._expanded) { - this._expanded = data.expanded; - validChanges.expanded = this._expanded; - } - - if (data.editSymbology !== undefined && data.editSymbology !== this._editSymbology) { - this._editSymbology = data.editSymbology; - validChanges.editSymbology = this._editSymbology; - } - - if (data.operator !== undefined && data.operator !== this.operator) { - this._operator = data.operator; - validChanges.operator = this._operator; - } - - return validChanges; - } - - get operator(): Operator { - return this._operator; - } - - get name(): string { - return this._name; - } - - get symbology(): S { - return this._symbology; - } - - get expanded(): boolean { - return this._expanded; - } - - get visible(): boolean { - return this._visible; - } - - get editSymbology(): boolean { - return this._editSymbology; - } - - abstract getLayerType(): LayerType; - - toDict(): LayerDict { - return { - name: this.name, - operator: this._operator.toDict(), - symbology: this.symbology.toDict(), - expanded: this.expanded, - visible: this.visible, - editSymbology: this.editSymbology, - type: this.getLayerType(), - typeOptions: this.typeOptions, - }; - } - - protected get typeOptions(): LayerTypeOptionsDict { - return {}; - } -} - -export class VectorLayer extends Layer { - clustered = false; - - static fromDict(dict: LayerDict, operatorMap = new Map()): Layer { - const operator = Operator.fromDict(dict.operator, operatorMap); - const typeOptions = dict.typeOptions as VectorLayerTypeOptionsDict; - - const clustered = (typeOptions && typeOptions.clustered && typeOptions.clustered) || false; - - return new VectorLayer({ - name: dict.name, - operator, - symbology: AbstractSymbology.fromDict(dict.symbology) as AbstractVectorSymbology, - visible: dict.visible, - expanded: dict.expanded, - editSymbology: dict.editSymbology, - clustered, - }); - } - - constructor(config: VectorLayerConfig) { - super(config); - this.clustered = !!config.clustered; - } - - getLayerType(): LayerType { - return 'vector'; - } - - protected get typeOptions(): VectorLayerTypeOptionsDict { - return { - clustered: this.clustered, - }; - } -} - -export class RasterLayer extends Layer { - static fromDict(dict: LayerDict, operatorMap = new Map()): Layer { - const operator = Operator.fromDict(dict.operator, operatorMap); - const symbology = AbstractSymbology.fromDict(dict.symbology) as AbstractRasterSymbology | MappingRasterSymbology; - - return new RasterLayer({ - name: dict.name, - operator, - symbology, - visible: dict.visible, - expanded: dict.expanded, - editSymbology: dict.editSymbology, - }); - } - - constructor(config: RasterLayerConfig) { - super(config); - if (!config.symbology.unit) { - config.symbology.unit = config.operator.units.get('value'); - } - } - - getLayerType(): LayerType { - return 'raster'; - } -} diff --git a/projects/wave-core/src/lib/layers/layer.service.ts b/projects/wave-core/src/lib/layers/layer.service.ts deleted file mode 100644 index e698993d..00000000 --- a/projects/wave-core/src/lib/layers/layer.service.ts +++ /dev/null @@ -1,150 +0,0 @@ -import {map} from 'rxjs/operators'; -import {BehaviorSubject, Observable} from 'rxjs'; - -import {Injectable} from '@angular/core'; - -import {Set as ImmutableSet} from 'immutable'; - -import {Layer} from './layer.model'; -import {FeatureID} from '../queries/geojson.model'; -import {AbstractSymbology} from './symbology/symbology.model'; - -export interface SelectedFeatures { - selected: ImmutableSet; - add?: ImmutableSet; - remove?: ImmutableSet; - focus?: FeatureID; -} - -/** - * A service that is responsible for managing the active layer array. - */ -@Injectable() -export class LayerService { - private selectedLayer$: BehaviorSubject> = new BehaviorSubject(undefined); - private selectedFeatures$: BehaviorSubject = new BehaviorSubject({ - selected: ImmutableSet(), - }); - private isAnyLayerSelected$: Observable; - - constructor() { - this.isAnyLayerSelected$ = this.getSelectedLayerStream().pipe(map((layer) => layer !== undefined)); - } - - /** - * Set a new selected layer. - * Does nothing if the layer is not within the list. - * @param layer The layer to select. - */ - setSelectedLayer(layer: Layer) { - if (layer !== this.selectedLayer$.value) { - this.selectedLayer$.next(layer); - this.selectedFeatures$.next({ - selected: ImmutableSet(), - }); - } - } - - /** - * @returns The currently selected layer as stream. - */ - getSelectedLayerStream(): Observable> { - return this.selectedLayer$.asObservable(); - } - - /** - * @returns The currently selected layer. - */ - getSelectedLayer(): Layer { - return this.selectedLayer$.getValue(); - } - - /** - * @returns a stream indicating if any layer is selected. - */ - getIsAnyLayerSelectedStream(): Observable { - return this.isAnyLayerSelected$; - } - - /** - * Create the suitable layer type and initialize the callbacks. - */ - /* - createLayerFromDict( - dict: LayerDict, - operatorMap = new Map() - ): Layer { - switch (dict.type) { - case 'raster': - return RasterLayer.fromDict( - dict, - //operator => this.mappingQueryService.getColorizerStream(operator), - //operator => this.mappingQueryService.getProvenanceStream(operator), - operatorMap - ); - case 'vector': - return VectorLayer.fromDict( - dict, - // (operator, clustered) => - // this.mappingQueryService.getWFSDataStreamAsGeoJsonFeatureCollection({ - // operator, clustered, - // }), - // operator => this.mappingQueryService.getProvenanceStream(operator), - operatorMap - ); - default: - throw 'LayerService.createLayerFromDict: Unknown LayerType ->' + dict; - } - } - */ - - /** - * @returns The currently selected features as stream. - */ - getSelectedFeaturesStream() { - return this.selectedFeatures$.asObservable(); - } - - /** - * @returns The currently selected features. - */ - getSelectedFeatures(): SelectedFeatures { - return this.selectedFeatures$.value; - } - - updateSelectedFeatures(add: Array, remove: Array): void { - const currentSelected = this.selectedFeatures$.value.selected; - const actualRemove = ImmutableSet(remove).intersect(currentSelected); - const actualSelected = currentSelected.subtract(actualRemove); - const actualAdd = ImmutableSet(add).subtract(actualSelected); - if (actualAdd.size > 0 || actualRemove.size > 0) { - let next: SelectedFeatures = { - selected: actualSelected.union(actualAdd), - add: actualAdd, - remove: actualRemove, - }; - if (actualAdd.size > 0) { - next.focus = add[add.length - 1]; - } - - // console.log('featureIds next', next); - this.selectedFeatures$.next(next); - } - } - - setSelectedFeatures(selection: Array): void { - const currentSelected = this.selectedFeatures$.value.selected; - const newSelected = ImmutableSet(selection); - if (newSelected.size > 0) { - let next: SelectedFeatures = { - selected: newSelected, - add: newSelected, - remove: currentSelected, - }; - if (newSelected.size > 0) { - next.focus = selection[selection.length - 1]; - } - this.selectedFeatures$.next(next); - } - } -} diff --git a/projects/wave-core/src/lib/layers/legend/legend-raster/mapping-raster-legend.component.html b/projects/wave-core/src/lib/layers/legend/legend-raster/mapping-raster-legend.component.html deleted file mode 100644 index 7bd0c403..00000000 --- a/projects/wave-core/src/lib/layers/legend/legend-raster/mapping-raster-legend.component.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - Interpolation - {{ interpolationToName(symbology?.unit?.interpolation) }} - - - Measurement - {{ symbology?.unit?.measurement }} - - - Unit - {{ symbology?.unit?.unit }} - - - - - - - - {{ breakpoint.value | number: numberPipeParameters }} - {{ unitToString(symbology?.unit) }} - - - -
- - {{ symbology?.unit?.classes?.get(breakpoint.value) }} -
- -
- diff --git a/projects/wave-core/src/lib/layers/legend/legend-raster/mapping-raster-legend.component.scss b/projects/wave-core/src/lib/layers/legend/legend-raster/mapping-raster-legend.component.scss deleted file mode 100644 index 03912607..00000000 --- a/projects/wave-core/src/lib/layers/legend/legend-raster/mapping-raster-legend.component.scss +++ /dev/null @@ -1,35 +0,0 @@ -:host { - padding-top: 4px; - padding-left: 8px; - padding-right: 0px; - padding-bottom: 8px; -} - -.legend { - display: table; - font-size: 12px; -} -tr { - min-height: 20px; -} - -td { - padding: 2px; -} - -.gradient { - min-width: 20px; - border: #000 solid 1px; -} - -.classes { - vertical-align: top; -} - -.icon { - margin-bottom: 1px !important; - margin-top: 1px !important; - min-height: 20px !important; - min-width: 20px !important; - border: #000 solid 1px; -} diff --git a/projects/wave-core/src/lib/layers/legend/legend-raster/mapping-raster-legend.component.ts b/projects/wave-core/src/lib/layers/legend/legend-raster/mapping-raster-legend.component.ts deleted file mode 100644 index 7781a88b..00000000 --- a/projects/wave-core/src/lib/layers/legend/legend-raster/mapping-raster-legend.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -import {ChangeDetectionStrategy, Component, OnChanges, SimpleChanges} from '@angular/core'; -import {MappingRasterSymbology} from '../../symbology/symbology.model'; -import {RasterLegendComponent} from './raster-legend.component'; -import {Interpolation, interpolationToName, Unit} from '../../../operators/unit.model'; -import {ColorBreakpoint} from '../../../colors/color-breakpoint.model'; - -/** - * The raster legend component. - */ -@Component({ - selector: 'wave-mapping-raster-legend', - templateUrl: 'mapping-raster-legend.component.html', - styleUrls: ['mapping-raster-legend.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class MappingRasterLegendComponent extends RasterLegendComponent implements OnChanges { - /** - * Parameters to use with the number pipe in the template. - */ - numberPipeParameters = '1.0-0'; - - /** - * Get a string representation of a Unit. - */ - unitToString(unit: Unit): string { - if (unit instanceof Unit && unit.unit !== Unit.defaultUnit.unit) { - return unit.unit; - } else { - return ''; - } - } - - /** - * Get the name of an interpolation. - */ - interpolationToName(interpolation: Interpolation): string { - return interpolationToName(interpolation); - } - - ngOnChanges(changes: SimpleChanges): void { - if (changes.symbology) { - const symbology = changes.symbology.currentValue as S; - this.numberPipeParameters = MappingRasterLegendComponent.calculateNumberPipeParameters(symbology.colorizer.breakpoints); - } - } - - private static calculateNumberPipeParameters(breakpoints: Array): string { - const firstNumber = (breakpoints[0].value as number).toString(10); - const lastNumber = (breakpoints[breakpoints.length - 1].value as number).toString(10); - const decimalPlacesFirst = firstNumber.indexOf('.') >= 0 ? firstNumber.split('.')[1].length : 0; - const decimalPlacesLast = lastNumber.indexOf('.') >= 0 ? lastNumber.split('.')[1].length : 0; - const maximumDecimalPlaces = Math.max(decimalPlacesFirst, decimalPlacesLast) + 2; - - return `1.0-${maximumDecimalPlaces}`; - } -} diff --git a/projects/wave-core/src/lib/layers/legend/legend-raster/raster-legend.component.ts b/projects/wave-core/src/lib/layers/legend/legend-raster/raster-legend.component.ts deleted file mode 100644 index 77a0f1d1..00000000 --- a/projects/wave-core/src/lib/layers/legend/legend-raster/raster-legend.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {ChangeDetectionStrategy, Component} from '@angular/core'; -import {LegendComponent} from '../legend.component'; -import {AbstractRasterSymbology} from '../../symbology/symbology.model'; - -@Component({ - selector: 'wave-legend-raster', - template: ` This is a generic raster layer `, - styleUrls: [], - // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['symbology'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class RasterLegendComponent extends LegendComponent {} diff --git a/projects/wave-core/src/lib/layers/legend/legend-vector/vector-legend-component.html b/projects/wave-core/src/lib/layers/legend/legend-vector/vector-legend-component.html deleted file mode 100644 index 537cbd3f..00000000 --- a/projects/wave-core/src/lib/layers/legend/legend-vector/vector-legend-component.html +++ /dev/null @@ -1,40 +0,0 @@ -
-
- - - - - - - - Default color -
-
- - {{fillColorAttribute}} -
-
- - - - - - - - {{iv.value}} -
-
- - {{strokeColorAttribute}} -
-
- - - - - - - - {{iv.value}} -
-
diff --git a/projects/wave-core/src/lib/layers/legend/legend-vector/vector-legend.component.scss b/projects/wave-core/src/lib/layers/legend/legend-vector/vector-legend.component.scss deleted file mode 100644 index 4ec8986e..00000000 --- a/projects/wave-core/src/lib/layers/legend/legend-vector/vector-legend.component.scss +++ /dev/null @@ -1,23 +0,0 @@ -:host { - padding-left: 8px; - padding-right: 0px; -} - -.segment:first-child { - margin-top: 4px; -} - -.segment { - font-size: 12px; - // height: 20px; -} - -.segment_head { - margin-top: 4px; - margin-left: 24px; - font-weight: bold; -} - -.segment:last-child { - margin-bottom: 4px; -} diff --git a/projects/wave-core/src/lib/layers/legend/legend-vector/vector-legend.component.ts b/projects/wave-core/src/lib/layers/legend/legend-vector/vector-legend.component.ts deleted file mode 100644 index 3d88ce52..00000000 --- a/projects/wave-core/src/lib/layers/legend/legend-vector/vector-legend.component.ts +++ /dev/null @@ -1,83 +0,0 @@ -import {ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges} from '@angular/core'; -import {SymbologyType, VectorSymbology} from '../../symbology/symbology.model'; -import {TRANSPARENT} from '../../../colors/color'; - -import {PolygonIconStyle} from '../../layer-icons/polygon-icon/polygon-icon.component'; -import {PointIconStyle} from '../../layer-icons/point-icon/point-icon.component'; -import {LineIconStyle} from '../../layer-icons/line-icon/line-icon.component'; - -interface IconValue { - icon: PointIconStyle | LineIconStyle | PolygonIconStyle; - value: string | number; -} - -@Component({ - selector: 'wave-vector-legend', - templateUrl: 'vector-legend-component.html', - styleUrls: ['vector-legend.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class VectorLegendComponent implements OnChanges { - readonly ST = SymbologyType; - - @Input() - showDefaultStyle = true; - - @Input() - symbology: S; - fillColorAttribute: string | undefined; - fillStyles: Array = []; - strokeColorAttribute: string | undefined; - strokeStyles: Array = []; - - constructor() { - this.updateStyles(); - } - - ngOnChanges(changes: SimpleChanges): void { - this.updateStyles(); - } - - private updateStyles() { - this.fillColorAttribute = this.symbology && this.symbology.fillColorAttribute ? this.symbology.fillColorAttribute : undefined; - this.fillStyles = VectorLegendComponent.fillColorIconValue(this.symbology); - this.strokeColorAttribute = this.symbology && this.symbology.strokeColorAttribute ? this.symbology.strokeColorAttribute : undefined; - this.strokeStyles = VectorLegendComponent.strokeColorIconValue(this.symbology); - } - - static fillColorIconValue(vectorSymbology: VectorSymbology): Array { - if (!vectorSymbology || !vectorSymbology.fillColorizer || !vectorSymbology.fillColorizer.breakpoints) { - return []; - } - - return vectorSymbology.fillColorizer.breakpoints.map((b) => { - return { - icon: { - strokeWidth: vectorSymbology.strokeWidth, - strokeDashStyle: vectorSymbology.strokeDashStyle ? vectorSymbology.strokeDashStyle : [], - strokeRGBA: TRANSPARENT, - fillRGBA: b.rgba, - }, - value: b.value, - }; - }); - } - - static strokeColorIconValue(vectorSymbology: VectorSymbology): Array { - if (!vectorSymbology || !vectorSymbology.strokeColorizer || !vectorSymbology.strokeColorizer.breakpoints) { - return []; - } - - return vectorSymbology.strokeColorizer.breakpoints.map((b) => { - return { - icon: { - strokeWidth: vectorSymbology.strokeWidth, - strokeDashStyle: vectorSymbology.strokeDashStyle ? vectorSymbology.strokeDashStyle : [], - strokeRGBA: b.rgba, - fillRGBA: TRANSPARENT, - }, - value: b.value, - }; - }); - } -} diff --git a/projects/wave-core/src/lib/layers/legend/legend.component.html b/projects/wave-core/src/lib/layers/legend/legend.component.html deleted file mode 100644 index 220c351a..00000000 --- a/projects/wave-core/src/lib/layers/legend/legend.component.html +++ /dev/null @@ -1 +0,0 @@ -LegendTypeId: {{ symbology.symbologyTypeId }} diff --git a/projects/wave-core/src/lib/layers/legend/legend.component.scss b/projects/wave-core/src/lib/layers/legend/legend.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/layers/legend/legend.component.ts b/projects/wave-core/src/lib/layers/legend/legend.component.ts deleted file mode 100644 index 14791d76..00000000 --- a/projects/wave-core/src/lib/layers/legend/legend.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {Component, Input} from '@angular/core'; - -import {AbstractSymbology} from '../symbology/symbology.model'; - -/** - * A simple legend component. - */ -@Component({ - selector: 'wave-legendary', - templateUrl: 'legend.component.html', -}) -export class LegendComponent { - @Input() symbology: S; -} diff --git a/projects/wave-core/src/lib/layers/symbology/stroke-dash-select/stroke-dash-select.component.html b/projects/wave-core/src/lib/layers/symbology/stroke-dash-select/stroke-dash-select.component.html deleted file mode 100644 index ca5ac061..00000000 --- a/projects/wave-core/src/lib/layers/symbology/stroke-dash-select/stroke-dash-select.component.html +++ /dev/null @@ -1,9 +0,0 @@ - - Stroke Dash Select - - - {{ dashStyleName(line) }} - - - - diff --git a/projects/wave-core/src/lib/layers/symbology/stroke-dash-select/stroke-dash-select.component.scss b/projects/wave-core/src/lib/layers/symbology/stroke-dash-select/stroke-dash-select.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/layers/symbology/stroke-dash-select/stroke-dash-select.component.ts b/projects/wave-core/src/lib/layers/symbology/stroke-dash-select/stroke-dash-select.component.ts deleted file mode 100644 index 4dc61922..00000000 --- a/projects/wave-core/src/lib/layers/symbology/stroke-dash-select/stroke-dash-select.component.ts +++ /dev/null @@ -1,108 +0,0 @@ -import {ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnChanges, SimpleChanges} from '@angular/core'; -import {DomSanitizer, SafeHtml} from '@angular/platform-browser'; -import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; -import {StrokeDashStyle} from '../symbology.model'; - -/** - * @title Basic select - */ -@Component({ - selector: 'wave-stroke-dash-select', - templateUrl: 'stroke-dash-select.component.html', - styleUrls: ['stroke-dash-select.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - providers: [{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrokeDashSelectComponent), multi: true}], -}) -export class StrokeDashSelectComponent implements ControlValueAccessor, OnChanges { - static svgPrefix = ''; - - @Input() lines: StrokeDashStyle[] = [[], [5, 5], [9, 3, 3]]; - - _strokeDashStyle: StrokeDashStyle = []; - onTouched: () => void; - onChange: (_: StrokeDashStyle) => void = undefined; - - get strokeDashStyle(): StrokeDashStyle { - return this._strokeDashStyle; - } - - set strokeDashStyle(strokeDashStyle: StrokeDashStyle) { - if (!strokeDashStyle) { - this._strokeDashStyle = []; - this.notify(); - this.changeDetectorRef.markForCheck(); - } - - if (!!strokeDashStyle && strokeDashStyle !== this._strokeDashStyle) { - this._strokeDashStyle = strokeDashStyle; - this.notify(); - this.changeDetectorRef.markForCheck(); - } - } - - constructor(public domSanitizer: DomSanitizer, private changeDetectorRef: ChangeDetectorRef) {} - - protected generateViewSvgString(dashArray: Array): string { - if (!!dashArray && dashArray.length > 0) { - return ( - StrokeDashSelectComponent.svgPrefix + - StrokeDashSelectComponent.svgDashPrefix + - dashArray.join(',') + - StrokeDashSelectComponent.svgPostfix - ); - } - return StrokeDashSelectComponent.svgPrefix + StrokeDashSelectComponent.svgPostfix; - } - - generateViewImage(dashArray: Array): SafeHtml { - const svgString = this.generateViewSvgString(dashArray); - return this.domSanitizer.bypassSecurityTrustHtml(svgString); - } - - dashStyleName(dashArray: Array): string { - if (!!dashArray && dashArray.length > 1) { - return 'Dashed Line'; - } - return 'Solid Line'; - } - - registerOnChange(fn: (_: StrokeDashStyle) => void): void { - if (fn) { - this.onChange = fn; - this.notify(); - } - } - - registerOnTouched(fn: () => void): void { - if (fn) { - this.onTouched = fn; - } - } - - ngOnChanges(changes: SimpleChanges) { - for (const propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - case 'lines': { - this.changeDetectorRef.markForCheck(); - break; - } - default: { - /* DO NOTHING*/ - } - } - } - } - - notify() { - if (this.onChange) { - this.onChange(this.strokeDashStyle); - } - } - - writeValue(strokeDashStyle: StrokeDashStyle): void { - this.strokeDashStyle = strokeDashStyle; - } -} diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-editor/symbology-editor.component.html b/projects/wave-core/src/lib/layers/symbology/symbology-editor/symbology-editor.component.html deleted file mode 100644 index 301180af..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-editor/symbology-editor.component.html +++ /dev/null @@ -1,87 +0,0 @@ -Symbology Editor - - -

The Symbology Editor enables customization of the style for vector or raster layers. Use the first field to select a layer.

-

- Raster data: -

-

- The Global Layer Properties define the default visualization parameters. The layer Opacity is adjustable in a range - from 0 to 100 %. You can choose a NoData color for pixels with the nodata value. Use the picker tool to select the desired - RGB color and opacity. This also applies to the Overflow color, which indicates the pixels with values without coloring - rules. -

-

- The Color Map section provides an overview of the pixel values with a frequency plot, which also allows to adapt the color - with respect to the raster values. The plot refers to the field of view shown in the map. If Sync map and histogram is - turned on, the histogram updates if the map view changes. To specify the value range of interest, you can set a minimum and maximum - pixel value. You can choose a color ramp from a variety of color schemes (Colormap name) and reverse it, if desired. - Additionally, different functions for the step distribution can be selected (linear, logarithmic, square root function, square - function). Consider that the logarithmic function requires positive values (>0). The number of Color steps is also kept flexible and - can be set to a number between 2 and 16. Click Create color table to apply your adjustments. -

-

- The Color Table section allows fine grained changes to colors. The gradient defines the interpolation between values. You - can dynamically add and remove color steps by clicking the minus and plus symbols or select distinct RGBA values for a specific - color step value. -

-

- Vector data: -

-

- Vector features are shown in the map as points, lines or polygons. The Global Layer Properties define the default - visualization parameters. Points have a global Radius, which is used if no other rules exist. All vector features have a - stroke. You can adapt the stroke width and color. Points and Polygons have a fill color. As all other global settings, this is - overwritten by other style rules. -

-

- If the layer is a clustered point layer, the radius refers to the minimum point radius. You need to zoom in and out (or pan) to see - the effect. -

-
- - - - {{ l.name }} - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - > - - -
diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-editor/symbology-editor.component.scss b/projects/wave-core/src/lib/layers/symbology/symbology-editor/symbology-editor.component.scss deleted file mode 100644 index ca85fb3d..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-editor/symbology-editor.component.scss +++ /dev/null @@ -1,12 +0,0 @@ -:host { - display: block; - padding: 1rem; -} - -mat-divider { - padding-bottom: 1rem; -} - -mat-form-field { - width: 100%; -} diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-editor/symbology-editor.component.ts b/projects/wave-core/src/lib/layers/symbology/symbology-editor/symbology-editor.component.ts deleted file mode 100644 index 89418a6c..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-editor/symbology-editor.component.ts +++ /dev/null @@ -1,70 +0,0 @@ -import {ChangeDetectionStrategy, Component, Input, OnDestroy} from '@angular/core'; -import {AbstractSymbology, SymbologyType} from '../symbology.model'; -import {Layer} from '../../layer.model'; -import {ProjectService} from '../../../project/project.service'; -import {Subject, Subscription} from 'rxjs'; -import {debounceTime} from 'rxjs/operators'; -import {Config} from '../../../config.service'; - -/** - * The symbology editor component takes a Layer as input and provides multiple ways to change its symbology. - * Changes are sent to the ProjectService. - */ -@Component({ - selector: 'wave-symbology-editor', - templateUrl: 'symbology-editor.component.html', - styleUrls: ['symbology-editor.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class SymbologyEditorComponent implements OnDestroy { - // make visible in template - /* eslint-disable @typescript-eslint/naming-convention, no-underscore-dangle, id-blacklist, id-match */ - readonly ST = SymbologyType; - /* eslint-enable */ - - /** - * input to hide/show a layer selection - */ - @Input() showLayerSelect = false; - - /** - * input to submit the layer with the symbology to edit - */ - @Input() layer: Layer = undefined; - - // The list with all valid layers, required for the layer selection. - validLayers: Array> = undefined; - private subscriptions: Array = []; - private layerChanges = new Subject<[Layer, AbstractSymbology]>(); - - constructor(private config: Config, public projectService: ProjectService) { - // This subscription updates the valid layer list. - const layerStreamSubscription = this.projectService - .getLayerStream() - .subscribe((projectLayers) => (this.validLayers = projectLayers)); - this.subscriptions.push(layerStreamSubscription); - // This subscription sends layer / symbology changes to the project service. - const layerChangesSubscription = this.layerChanges - .pipe(debounceTime(config.DELAYS.DEBOUNCE)) - .subscribe(([layer, symbology]) => this.projectService.changeLayer(layer, {symbology})); - this.subscriptions.push(layerChangesSubscription); - } - - /** - * Indicates if the current layer is a valid layer - */ - get isValidLayer(): boolean { - return !!this.layer && !!this.layer.symbology && !!this.validLayers.find((x) => x === this.layer); - } - - /** - * Submit a layer and the desired symbology to update the layer accordingly. - */ - update_symbology(layer: Layer, symbology: AbstractSymbology) { - this.layerChanges.next([layer, symbology]); - } - - ngOnDestroy(): void { - this.subscriptions.forEach((x) => x.unsubscribe()); - } -} diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster-mapping-colorizer.component.html b/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster-mapping-colorizer.component.html deleted file mode 100644 index 5d2b6450..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster-mapping-colorizer.component.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - map - Global Layer Properties - - - -
- - - - - - -
Opacity - - - {{ slo.displayValue }} %
-
- -
- - - - -
-
-
- - - - - looks - Color Map - - - - -
- - -
-
- - Sync map and histogram - -
- - - - -
-
- - - - - color_lens - Color Table - - - - - - -
diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster-mapping-colorizer.component.scss b/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster-mapping-colorizer.component.scss deleted file mode 100644 index d14c3760..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster-mapping-colorizer.component.scss +++ /dev/null @@ -1,46 +0,0 @@ -table { - width: 100%; - font-size: 0.8em; -} - -mat-divider { - padding-bottom: 1rem; -} - -.color_cell { - text-align: center; - min-width: 2rem; - min-height: 2rem; - color: black !important; - text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff !important; -} - -td:first-child, -td:last-child { - width: 1%; - white-space: nowrap; -} - -mat-slider { - min-width: unset; - width: 100%; -} - -.symbology-headers-align .mat-expansion-panel-header-title, -.symbology-headers-align .mat-expansion-panel-header-description { - flex-basis: 0; - align-items: center; -} - -.symbology-headers-align .mat-expansion-panel-header-description { - justify-content: space-between; - align-items: center; -} - -.histogram { - width: 100%; -} - -.histogram .mat-progress-spinner { - margin: 0 auto; -} diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster-mapping-colorizer.component.ts b/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster-mapping-colorizer.component.ts deleted file mode 100644 index 0f76df39..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster-mapping-colorizer.component.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { - Component, - Input, - Output, - EventEmitter, - ChangeDetectionStrategy, - OnChanges, - SimpleChanges, - OnDestroy, - AfterViewInit, - OnInit, -} from '@angular/core'; - -import {MappingRasterSymbology} from '../symbology.model'; -import {ColorizerData} from '../../../colors/colorizer-data.model'; -import {ColorBreakpoint} from '../../../colors/color-breakpoint.model'; -import {RasterLayer} from '../../layer.model'; -import {BehaviorSubject, combineLatest as observableCombineLatest, ReplaySubject, Subscription} from 'rxjs'; -import {HistogramData} from '../../../plots/histogram/histogram.component'; -import {ProjectService} from '../../../project/project.service'; -import {Operator} from '../../../operators/operator.model'; -import {HistogramType} from '../../../operators/types/histogram-type.model'; -import {DataType} from '../../../operators/datatype.model'; -import {Unit} from '../../../operators/unit.model'; -import {debounceTime, filter, map, startWith} from 'rxjs/operators'; -import {ResultTypes} from '../../../operators/result-type.model'; -import {MappingQueryService} from '../../../queries/mapping-query.service'; -import {MapService} from '../../../map/map.service'; -import {Config} from '../../../config.service'; -import {MatSliderChange} from '@angular/material/slider'; -import {MatSlideToggleChange} from '@angular/material/slide-toggle'; - -/** - * The symbology editor component for raster data, which is colorized by the mapping backend - */ -@Component({ - selector: 'wave-symbology-raster-mapping-colorizer', - templateUrl: 'symbology-raster-mapping-colorizer.component.html', - styleUrls: ['symbology-raster-mapping-colorizer.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class SymbologyRasterMappingColorizerComponent implements OnChanges, OnDestroy, AfterViewInit, OnInit { - @Input() layer: RasterLayer; - @Output() symbologyChanged: EventEmitter = new EventEmitter(); - - symbology: MappingRasterSymbology; - - // The min value used for color table generation - layerMinValue: number | undefined = undefined; - // The max value used for color table generation - layerMaxValue: number | undefined = undefined; - // A subject with the histogram data of the current layer view - layerHistogramData$: ReplaySubject = new ReplaySubject(1); - // Subject indicating if the histogram is still processing - layerHistogramDataLoading$ = new BehaviorSubject(false); - // Histogram auto reload enabled / disabled - layerHistogramAutoReloadEnabled = true; - private layerHistogramDataSubscription: Subscription = undefined; - - constructor( - public projectService: ProjectService, - public mappingQueryService: MappingQueryService, - public mapService: MapService, - public config: Config, - ) {} - - /** - * Set the max value to use for color table generation - */ - updateLayerMinValue(min: number) { - if (this.layerMinValue !== min) { - this.layerMinValue = min; - } - } - - /** - * Set the max value to use for color table generation - */ - updateLayerMaxValue(max: number) { - if (this.layerMaxValue !== max) { - this.layerMaxValue = max; - } - } - - /** - * Set the opacity value from a slider change event - */ - updateOpacity(event: MatSliderChange) { - this.symbology.opacity = event.value === undefined || event.value === 0 ? 0 : event.value / 100; - this.update(); - } - - /** - * Set the overflow color - */ - updateOverflowColor(colorBreakpoint: ColorBreakpoint) { - if (colorBreakpoint) { - this.symbology.overflowColor = colorBreakpoint; - this.update(); - } - } - - /** - * Set the no data color - */ - updateNoDataColor(colorBreakpoint: ColorBreakpoint) { - if (colorBreakpoint) { - this.symbology.noDataColor = colorBreakpoint; - this.update(); - } - } - - /** - * Set the symbology colorizer - */ - updateColorizer(colorizerData: ColorizerData) { - if (colorizerData) { - this.symbology.colorizer = colorizerData; - this.update(); - } - } - - /** - * Access the current colorizer min value. May be undefined. - */ - get colorizerMinValue(): number | undefined { - return this.symbology.colorizer.firstBreakpoint.value as number; - } - - /** - * Access the current colorizer max value. May be undefined. - */ - get colorizerMaxValue(): number | undefined { - return this.symbology.colorizer.lastBreakpoint.value as number; - } - - /** - * Sets the current (working) symbology to the one of the current layer. - */ - updateSymbologyFromLayer() { - if (!this.layer || !this.layer.symbology || this.layer.symbology.equals(this.symbology)) { - return; - } - this.symbology = this.layer.symbology; - } - - /** - * Sets the layer min/max values from the colorizer. - */ - updateLayerMinMaxFromColorizer() { - this.updateLayerMaxValue(this.colorizerMinValue); - this.updateLayerMaxValue(this.colorizerMaxValue); - } - - /** - * Update the histogram auto reload setting. - * @param event contains a checked: boolean value. - */ - updateHistogramAutoReload(event: MatSlideToggleChange) { - this.layerHistogramAutoReloadEnabled = event.checked; - } - - private update() { - this.symbologyChanged.emit(this.symbology.clone()); - } - - ngOnChanges(changes: SimpleChanges): void { - for (const propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - case 'layer': { - if (changes['layer'].firstChange) { - break; - } - this.updateSymbologyFromLayer(); - this.updateLayerMinMaxFromColorizer(); - // this.updateLayerHistogramOperator(); - this.reinitializeLayerHistogramDataSubscription(); - - break; - } - default: // DO NOTHING - } - } - } - - ngOnInit(): void { - this.updateSymbologyFromLayer(); - this.updateLayerMinMaxFromColorizer(); - } - - ngAfterViewInit(): void { - // this.updateLayerHistogramOperator(); - this.reinitializeLayerHistogramDataSubscription(); - } - - ngOnDestroy() { - this.layerHistogramDataSubscription.unsubscribe(); - } - - private reinitializeLayerHistogramDataSubscription() { - if (this.layerHistogramDataSubscription) { - this.layerHistogramDataSubscription.unsubscribe(); - } - - this.layerHistogramData$.next(undefined); - this.layerHistogramDataLoading$.next(true); - - const sub = observableCombineLatest( - observableCombineLatest( - this.projectService.getTimeStream(), - this.projectService.getProjectionStream(), - this.mapService.getViewportSizeStream(), - ).pipe( - filter((_) => this.layerHistogramAutoReloadEnabled), - debounceTime(this.config.DELAYS.DEBOUNCE), - ), - this.projectService.getLayerChangesStream(this.layer).pipe( - startWith({operator: true}), - filter((c) => c.operator !== undefined), - map((_) => this.buildHistogramOperator()), - ), - ).subscribe(([[projectTime, projection, viewport], histogramOperator]) => { - this.layerHistogramData$.next(undefined); - this.layerHistogramDataLoading$.next(true); - - this.mappingQueryService - .getPlotData({ - operator: histogramOperator, - time: projectTime, - extent: viewport.extent, - projection, - }) - .subscribe((data) => { - this.layerHistogramData$.next(data as HistogramData); - this.layerHistogramDataLoading$.next(false); - }); - }); - this.layerHistogramDataSubscription = sub; - } - - private buildHistogramOperator(): Operator { - return new Operator({ - operatorType: new HistogramType({ - attribute: 'value', - range: 'data', - }), - resultType: ResultTypes.PLOT, - projection: this.layer.operator.projection, - attributes: [], - dataTypes: new Map(), - units: new Map(), - rasterSources: [this.layer.operator], - }); - } -} diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster.component.html b/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster.component.html deleted file mode 100644 index c53d49e8..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster.component.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - -
Opacity - - - {{ slo.displayValue }} %
diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster.component.scss b/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster.component.scss deleted file mode 100644 index b3cd0545..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster.component.scss +++ /dev/null @@ -1,23 +0,0 @@ -table { - width: 100%; - font-size: 0.8em; -} - -.color_cell { - text-align: center; - min-width: 2rem; - min-height: 2rem; - color: black !important; - text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff !important; -} - -td:first-child, -td:last-child { - width: 1%; - white-space: nowrap; -} - -mat-slider { - min-width: unset; - width: 100%; -} diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster.component.ts b/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster.component.ts deleted file mode 100644 index 9aff678a..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-raster/symbology-raster.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {Component, Input, Output, EventEmitter} from '@angular/core'; - -import {AbstractRasterSymbology} from '../symbology.model'; -import {MatSliderChange} from '@angular/material/slider'; -import {Layer} from '../../layer.model'; - -/** - * A simple raster symbology component. - */ -@Component({ - selector: 'wave-symbology-raster', - templateUrl: 'symbology-raster.component.html', - styleUrls: ['symbology-raster.component.scss'], -}) -export class SymbologyRasterComponent { - @Input() layer: Layer; - @Output() symbologyChanged: EventEmitter = new EventEmitter(); - - updateOpacity(event: MatSliderChange) { - this.layer.symbology.opacity = event.value === undefined || event.value === 0 ? 0 : event.value / 100; - this.update(); - } - - update() { - this.symbologyChanged.emit(this.layer.symbology.clone()); - } -} diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-vectors/symbology-vector.component.html b/projects/wave-core/src/lib/layers/symbology/symbology-vectors/symbology-vector.component.html deleted file mode 100644 index 22f47cf7..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-vectors/symbology-vector.component.html +++ /dev/null @@ -1,241 +0,0 @@ - - - - - map - Global Layer Properties - - - - - - - - - - - - -
- Stroke width - - - - {{ sls.displayValue }} px -
- {{ radiusAttributePlaceholder }} - - - - {{ slr.displayValue }} px -
- - - - -
- - - - -
-
-
- - - - - color_lens - Fill Color By Attribute - - Define an attribute to color mapping to fill elements - - -
- - Enable Fill Color By Attribute - -
-
- - Fill Color Attribute - - {{ attribute.name }} ({{ attribute.type }}) - - - -
- -
- -
-
-
- - - - - color_lens - Stroke Color By Attribute - - Define an attribute to color mapping for the stroke of elements - - -
- - Enable Stroke Color Attribute - -
-
- - Stroke Color Attribute - - {{ attribute.name }} ({{ attribute.type }}) - - - -
- -
- -
-
-
- - - - - looks - Point Radius By Attribute - - Define an attribute to radius mapping for points - - -
- - Enable Radius By Attribute - -
-
- Note: The radius is clipped to the range [{{ minRadius }}, {{ maxRadius }}]. -
-
- - Radius Attribute - - {{ attribute.name }} ({{ attribute.type }}) - - - -
-
- -
-
-
- - - - - looks - Text By Attribute - - Define an attribute to display as text - - -
- - Enable Text By Attribute - -
-
- Note: The text is truncated after {{ maxTextChars }} characters. -
-
- - Text Attribute - - {{ attribute.name }} ({{ attribute.type }}) - - - -
-
- -
-
-
-
diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-vectors/symbology-vector.component.scss b/projects/wave-core/src/lib/layers/symbology/symbology-vectors/symbology-vector.component.scss deleted file mode 100644 index a33735c4..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-vectors/symbology-vector.component.scss +++ /dev/null @@ -1,28 +0,0 @@ -table { - width: 100%; - font-size: 0.8em; -} - -.color_cell { - cursor: pointer; - text-align: center; - min-width: 2rem; - min-height: 2rem; - color: black !important; - text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff !important; -} - -:host ::ng-deep .color-picker { - position: fixed !important; -} - -.symbology-headers-align .mat-expansion-panel-header-title, -.symbology-headers-align .mat-expansion-panel-header-description { - flex-basis: 0; - align-items: center; -} - -.symbology-headers-align .mat-expansion-panel-header-description { - justify-content: space-between; - align-items: center; -} diff --git a/projects/wave-core/src/lib/layers/symbology/symbology-vectors/symbology-vector.component.ts b/projects/wave-core/src/lib/layers/symbology/symbology-vectors/symbology-vector.component.ts deleted file mode 100644 index d89f0af1..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology-vectors/symbology-vector.component.ts +++ /dev/null @@ -1,352 +0,0 @@ -import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core'; - -import { - PointSymbology, - VectorSymbology, - StrokeDashStyle, - SymbologyType, - DEFAULT_POINT_CLUSTER_RADIUS_ATTRIBUTE, - MAX_ALLOWED_POINT_RADIUS, - MIN_ALLOWED_POINT_RADIUS, - DEFAULT_POINT_CLUSTER_TEXT_ATTRIBUTE, - MAX_ALLOWED_TEXT_LENGTH, -} from '../symbology.model'; -import {MatSlideToggleChange} from '@angular/material/slide-toggle'; -import {MatSliderChange} from '@angular/material/slider'; -import {ColorBreakpoint} from '../../../colors/color-breakpoint.model'; -import {VectorLayer} from '../../layer.model'; -import {DataTypes} from '../../../operators/datatype.model'; -import {ColorizerData} from '../../../colors/colorizer-data.model'; - -/** - * A simple interface to group attribute names with types - */ -interface Attribute { - name: string; - type: 'number' | 'text'; -} - -/** - * The symbology editor component for vector layers - */ -@Component({ - selector: 'wave-symbology-vector', - templateUrl: `symbology-vector.component.html`, - styleUrls: ['./symbology-vector.component.scss'], -}) -export class SymbologyVectorComponent implements OnChanges, OnInit { - // the min valid stroke width - static minStrokeWidth = 0; - - /** - * The vector layer for which the symbology is currently edited - */ - @Input() layer: VectorLayer | VectorLayer; - /** - * The event emitter propagating the changed symbology - */ - @Output() symbologyChanged = new EventEmitter(); - - // bounds for radius and text - readonly minRadius = MIN_ALLOWED_POINT_RADIUS; - readonly maxRadius = MAX_ALLOWED_POINT_RADIUS; - readonly maxTextChars = MAX_ALLOWED_TEXT_LENGTH; - - /** - * The working copy of the symbology - */ - symbology: VectorSymbology | PointSymbology; - - // enable / disable symbology features and stores for the selected attributes - fillByAttribute = false; - strokeByAttribute = false; - fillColorAttribute: Attribute; - strokeColorAttribute: Attribute; - radiusAttribute: Attribute; - radiusByAttribute: boolean; - textByAttribute: boolean; - textAttribute: Attribute; - attributes: Array; - numericAttributes: Array; - - constructor() {} - - ngOnChanges(changes: SimpleChanges) { - for (const propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - case 'layer': - this.updateSymbologyFromLayer(); - break; - default: - // DO NOTHING - } - } - } - - ngOnInit() { - this.updateSymbologyFromLayer(); - } - - /** - * set the symbology fill colorizer attribute from the local (selected) variables - */ - setFillColorizerAttribute() { - if (this.fillByAttribute && this.fillColorAttribute) { - this.symbology.setFillColorAndAttribute(this.fillColorAttribute.name); - this.symbology.fillColorizer.clear(); - this.symbology.fillColorizer.addBreakpoint({ - rgba: this.symbology.fillRGBA, - value: this.fillColorAttribute.type === 'number' ? 0 : '', - }); - } else { - this.symbology.clearFillColorAndAttribute(); - } - } - - /** - * set the radius attribute to the default for clustered points - */ - setRadiusAttributeForClustering() { - const symbology = this.symbology as PointSymbology; - this.radiusByAttribute = false; - symbology.radiusFactor = 1.0; - symbology.clustered = true; - symbology.radiusAttribute = DEFAULT_POINT_CLUSTER_RADIUS_ATTRIBUTE; - this.update(); - } - - /** - * set the text attribute to the default for clustered points - */ - setTextAttributeForClustering() { - this.textByAttribute = false; - this.symbology.textAttribute = DEFAULT_POINT_CLUSTER_TEXT_ATTRIBUTE; - this.update(); - } - - /** - * update the fill colorizer attribute using the slide toggle value - */ - updateFillColorizeByAttribute(event: MatSlideToggleChange) { - this.fillByAttribute = event.checked; - this.setFillColorizerAttribute(); - this.update(); - } - - /** - * set the stroke color attribute using the local (selected) variables - */ - setStrokeColorizerAttribute() { - if (this.strokeByAttribute && this.strokeColorAttribute) { - this.symbology.setStrokeColorAndAttribute(this.strokeColorAttribute.name); - this.symbology.strokeColorizer.clear(); - this.symbology.strokeColorizer.addBreakpoint({ - rgba: this.symbology.strokeRGBA, - value: this.strokeColorAttribute.type === 'number' ? 0 : '', - }); - } else { - this.symbology.clearStrokeColorAndAttribute(); - } - } - - /** - * update the stroke color attribute using the slide togle value - */ - updateStrokeColorizeByAttribute(event: MatSlideToggleChange) { - this.strokeByAttribute = event.checked; - this.setStrokeColorizerAttribute(); - this.update(); - } - - /** - * set the radius attribute using the local (selected) variables - */ - setRadiusAttribute() { - if (this.symbology instanceof PointSymbology) { - if (this.radiusByAttribute && this.radiusAttribute) { - this.symbology.setRadiusAttributeAndFactor(this.radiusAttribute.name); - } else { - this.symbology.clearRadiusAttribute(); - } - this.update(); - } - } - - /** - * update the stroke color attribute using the slide togle value - */ - updateRadiusByAttribute(event: MatSlideToggleChange) { - this.radiusByAttribute = event.checked; - this.setRadiusAttribute(); - } - - /** - * set the text attribute using the (selected) local variables - */ - setTextAttribute() { - if (this.textByAttribute && this.textAttribute) { - this.symbology.textAttribute = this.textAttribute.name; - } else { - this.symbology.clearTextAttribute(); - } - this.update(); - } - - /** - * update the text attribute using the slide togle value - */ - updateTextByAttribute(event: MatSlideToggleChange) { - this.textByAttribute = event.checked; - this.setTextAttribute(); - } - - private updateSymbologyFromLayer() { - if (!this.layer || !this.layer.symbology || this.layer.symbology.equals(this.symbology)) { - return; - } - const symbology = this.layer.symbology; - this.symbology = symbology; - this.fillByAttribute = !!symbology.fillColorAttribute; - this.strokeByAttribute = !!symbology.strokeColorAttribute; - this.gatherAttributes(); - this.fillColorAttribute = this.attributes.find((x) => x.name === symbology.fillColorAttribute); - this.fillByAttribute = !!this.fillColorAttribute; - this.strokeColorAttribute = this.attributes.find((x) => x.name === symbology.strokeColorAttribute); - this.strokeByAttribute = !!this.strokeColorAttribute; - if (symbology instanceof PointSymbology) { - this.radiusAttribute = this.attributes.find((x) => x.name === symbology.radiusAttribute); - this.radiusByAttribute = !!this.radiusAttribute; - } - this.textAttribute = this.attributes.find((x) => x.name === symbology.textAttribute); - this.textByAttribute = !!this.textAttribute; - } - - private gatherAttributes() { - const attributes: Array = []; - const numericAttributes: Array = []; - this.layer.operator.dataTypes.forEach((datatype, attribute) => { - if (DataTypes.ALL_NUMERICS.indexOf(datatype) >= 0) { - numericAttributes.push({ - name: attribute, - type: 'number', - }); - } else { - attributes.push({ - name: attribute, - type: 'text', - }); - } - }); - this.numericAttributes = numericAttributes; - this.attributes = [...numericAttributes, ...attributes]; - } - - /** - * emmit the current working symbology - */ - update() { - // return a clone (immutablility) - this.symbologyChanged.emit(this.symbology.clone()); - } - - /** - * update the stroke width unsing the slider value - */ - updateStrokeWidth(event: MatSliderChange) { - // guard against negative values - if (this.symbology.strokeWidth < SymbologyVectorComponent.minStrokeWidth) { - this.symbology.strokeWidth = SymbologyVectorComponent.minStrokeWidth; - } - - this.symbology.strokeWidth = event.value; - this.update(); - } - - updateStrokeDash(sds: StrokeDashStyle) { - if (!!sds && sds !== this.symbology.strokeDashStyle) { - this.symbology.strokeDashStyle = sds; - this.update(); - } - } - - /** - * update the stroke dash unsing the slider value - */ - updateRadius(event: MatSliderChange) { - if (!(this.symbology instanceof PointSymbology)) { - throw new Error('SymbologyVectorComponent: cant change radius for non point symbology'); - } - this.symbology.radius = event.value; - if (this.symbology.radius < this.minRadius) { - this.symbology.radius = this.minRadius; - } - if (this.symbology.radius > this.maxRadius) { - this.symbology.radius = this.maxRadius; - } - this.update(); - } - - /** - * update the fill with a color breakpoint - */ - updateFill(fill: ColorBreakpoint) { - if (fill && fill !== this.symbology.fillColorBreakpoint) { - this.symbology.fillColorBreakpoint = fill; - this.update(); - } - } - - /** - * update the stroke with a color breakpoint - */ - updateStroke(stroke: ColorBreakpoint) { - if (stroke && stroke !== this.symbology.strokeColorBreakpoint) { - this.symbology.strokeColorBreakpoint = stroke; - this.update(); - } - } - - /** - * update the fill colorizer with colorizer data - */ - updateFillColorizer(event: ColorizerData) { - if (event && this.symbology) { - this.symbology.setOrUpdateFillColorizer(event); - this.update(); - } - } - - /** - * update the stroke colorizer with colorizer data - */ - updateStrokeColorizer(event: ColorizerData) { - if (event && this.symbology) { - this.symbology.setOrUpdateStrokeColorizer(event); - this.update(); - } - } - - get fillColorAttributePlaceholder(): string { - return this.fillByAttribute ? 'Default Fill Color' : 'Fill Color'; - } - - get strokeColorAttributePlaceholder(): string { - return this.strokeByAttribute ? 'Default Stroke Color' : 'Stroke Color'; - } - - get radiusAttributePlaceholder(): string { - return this.radiusByAttribute || this.isClusteredPointSymbology ? 'Default Radius' : 'Radius'; - } - - get isClusteredPointSymbology(): boolean { - if (this.symbology instanceof PointSymbology) { - return this.symbology.clustered; - } - return false; - } - - get isPointSymbology(): boolean { - return this.symbology.getSymbologyType() === SymbologyType.COMPLEX_POINT; - } -} diff --git a/projects/wave-core/src/lib/layers/symbology/symbology.model.ts b/projects/wave-core/src/lib/layers/symbology/symbology.model.ts deleted file mode 100644 index b9ec7ab3..00000000 --- a/projects/wave-core/src/lib/layers/symbology/symbology.model.ts +++ /dev/null @@ -1,710 +0,0 @@ -import {Interpolation, Unit, UnitDict} from '../../operators/unit.model'; -import {Color, RgbaLike, RgbaTuple, TRANSPARENT, WHITE} from '../../colors/color'; -import {ColorizerData, IColorizerData, MappingRasterColorizerDict} from '../../colors/colorizer-data.model'; -import {ColorBreakpoint, ColorBreakpointDict} from '../../colors/color-breakpoint.model'; -import {Colormap} from '../../colors/colormaps/colormap.model'; - -/** - * List of the symbology types used in WAVE - */ -export enum SymbologyType { - RASTER, // UNUSED - SIMPLE_POINT, // DEPRECATED - CLUSTERED_POINT, // DEPRECATED - SIMPLE_LINE, // DEPRECATED - SIMPLE_VECTOR, // DEPRECATED - MAPPING_COLORIZER_RASTER, - ICON_POINT, // RESERVED - COMPLEX_POINT, - COMPLEX_VECTOR, - COMPLEX_LINE, -} - -// List of constants used by layer symbology. -export const DEFAULT_VECTOR_STROKE_COLOR: Color = Color.fromRgbaLike([0, 0, 0, 1]); -export const DEFAULT_VECTOR_FILL_COLOR: Color = Color.fromRgbaLike([255, 0, 0, 1]); -export const DEFAULT_VECTOR_HIGHLIGHT_STROKE_COLOR: Color = Color.fromRgbaLike([255, 255, 255, 1]); -export const DEFAULT_VECTOR_HIGHLIGHT_FILL_COLOR: Color = Color.fromRgbaLike([0, 153, 255, 1]); -export const DEFAULT_VECTOR_HIGHLIGHT_TEXT_COLOR: Color = Color.fromRgbaLike([255, 255, 255, 1]); -export const DEFAULT_POINT_RADIUS = 8; -export const DEFAULT_POINT_CLUSTER_RADIUS_ATTRIBUTE = '___radius'; -export const DEFAULT_POINT_CLUSTER_TEXT_ATTRIBUTE = '___numberOfPoints'; -export const MIN_ALLOWED_POINT_RADIUS = 1; -export const MAX_ALLOWED_POINT_RADIUS = 100; -export const MAX_ALLOWED_TEXT_LENGTH = 25; - -/** - * Serialization interface - */ -export interface SymbologyDict { - symbologyType: string; -} - -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ISymbology {} - -export type StrokeDashStyle = Array; - -/** - * The abstract symbology class with common methods. - */ -export abstract class AbstractSymbology implements ISymbology { - /** - * Deserialization logic to generate any Symbology from SymbologyDict. - */ - static fromDict(dict: SymbologyDict): AbstractSymbology { - switch (dict.symbologyType) { - case SymbologyType[SymbologyType.SIMPLE_POINT]: - case SymbologyType[SymbologyType.COMPLEX_POINT]: - return PointSymbology.createSymbology(dict as PointSymbologyDict); - - case SymbologyType[SymbologyType.CLUSTERED_POINT]: - return PointSymbology.createClusterSymbology(dict as VectorSymbologyDict); - - case SymbologyType[SymbologyType.SIMPLE_LINE]: - case SymbologyType[SymbologyType.COMPLEX_LINE]: - return LineSymbology.createSymbology(dict as VectorSymbologyDict); - - case SymbologyType[SymbologyType.SIMPLE_VECTOR]: - case SymbologyType[SymbologyType.COMPLEX_VECTOR]: - return VectorSymbology.createSymbology(dict as VectorSymbologyDict); - - case SymbologyType[SymbologyType.RASTER]: - case SymbologyType[SymbologyType.MAPPING_COLORIZER_RASTER]: - return MappingRasterSymbology.createSymbology(dict as RasterSymbologyDict); - default: - throw new Error('Unsupported AbstractSymbology'); - } - } - - abstract getSymbologyType(): SymbologyType; - - get symbologyType(): SymbologyType { - return this.getSymbologyType(); - } - - get symbologyTypeId(): string { - return SymbologyType[this.getSymbologyType()]; - } - - abstract clone(): AbstractSymbology; - - abstract toConfig(): ISymbology; - - abstract equals(other: AbstractSymbology): boolean; - - abstract toDict(): SymbologyDict; -} - -/** - * Configuration interface with optional fields for VectorSymbology. - */ -export interface VectorSymbologyConfig extends ISymbology { - fillRGBA?: RgbaLike; - strokeRGBA?: RgbaLike; - strokeWidth?: number; - fillColorizer?: IColorizerData; - fillColorAttribute?: string; - strokeColorizer?: IColorizerData; - strokeColorAttribute?: string; - strokeDashStyle?: StrokeDashStyle; - textAttribute?: string; - textColor?: RgbaLike; - textStrokeWidth?: number; -} - -/** - * Serialzation interface for VectorSymbology. - */ -interface VectorSymbologyDict extends SymbologyDict { - fillRGBA: RgbaTuple; - strokeRGBA: RgbaTuple; - strokeWidth: number; - fillColorizer: IColorizerData; - fillColorAttribute: string; - strokeColorizer: IColorizerData; - strokeColorAttribute: string; - strokeDashStyle: StrokeDashStyle; - textAttribute: string; - textColor: RgbaLike; - textStrokeWidth: number; -} - -/** - * The abstract VectorSymbology class. - */ -export abstract class AbstractVectorSymbology extends AbstractSymbology { - private _fillColorBreakpoint: ColorBreakpoint = new ColorBreakpoint({rgba: DEFAULT_VECTOR_FILL_COLOR, value: 'Default fill color'}); - private _strokeColorBreakpoint: ColorBreakpoint = new ColorBreakpoint({ - rgba: DEFAULT_VECTOR_STROKE_COLOR, - value: 'Default stroke color', - }); - - // common vector symbology fill - fillColorizer: ColorizerData; - fillColorAttribute: string = undefined; - // common vector symbology stroke - strokeWidth = 1; - strokeColorizer: ColorizerData; - strokeColorAttribute: string = undefined; - private _strokeDashStyle: StrokeDashStyle = undefined; - // common vector symbology text attribute - _textAttribute: string = undefined; - textColor: Color = undefined; - textStrokeWidth: number = undefined; - - /** - * Returns true if the symbology describes filled objects. - */ - abstract describesElementFill(): boolean; - - /** - * Returns true if the symbology describes elements with stroke. - */ - abstract describesElementStroke(): boolean; - - /** - * Returns true if the symbology describes points with radius. - */ - abstract describesPointsWithRadius(): boolean; - - set fillColorBreakpoint(colorBreakpoint: ColorBreakpoint) { - this._fillColorBreakpoint = colorBreakpoint; - } - - get fillColorBreakpoint(): ColorBreakpoint { - return this._fillColorBreakpoint; - } - - set strokeColorBreakpoint(colorBreakpoint: ColorBreakpoint) { - this._strokeColorBreakpoint = colorBreakpoint; - } - - get strokeColorBreakpoint(): ColorBreakpoint { - return this._strokeColorBreakpoint; - } - - set fillRGBA(color: Color) { - this._fillColorBreakpoint.setColor(color); - } - - get fillRGBA(): Color { - return this._fillColorBreakpoint.rgba; - } - - set strokeRGBA(color: Color) { - this._strokeColorBreakpoint.setColor(color); - } - - get strokeRGBA(): Color { - return this._strokeColorBreakpoint.rgba; - } - - set textAttribute(textAttribute: string) { - this._textAttribute = textAttribute; - } - - get textAttribute(): string { - return this._textAttribute; - } - - set strokeDashStyle(strokeDashStyle: StrokeDashStyle) { - this._strokeDashStyle = strokeDashStyle; - } - - get strokeDashStyle(): StrokeDashStyle { - return this._strokeDashStyle; - } - - setFillColorAndAttribute(name: string, clr: ColorizerData = ColorizerData.empty()) { - this.fillColorizer = clr; - this.fillColorAttribute = name; - } - - setOrUpdateFillColorizer(clr: ColorizerData): boolean { - if (clr && (!this.fillColorizer || !clr.equals(this.fillColorizer))) { - this.fillColorizer = clr; - return true; - } - return false; - } - - setStrokeColorAndAttribute(name: string, clr: ColorizerData = ColorizerData.empty()) { - this.strokeColorizer = clr; - this.strokeColorAttribute = name; - } - - setOrUpdateStrokeColorizer(clr: ColorizerData): boolean { - if (clr && (!this.strokeColorizer || !clr.equals(this.strokeColorizer))) { - this.strokeColorizer = clr; - return true; - } - return false; - } - - clearFillColorAndAttribute() { - this.fillColorAttribute = undefined; - this.fillColorizer = ColorizerData.empty(); - } - - clearStrokeColorAndAttribute() { - this.strokeColorAttribute = undefined; - this.strokeColorizer = ColorizerData.empty(); - } - - clearStrokeDashStyle() { - this.strokeDashStyle = undefined; - } - - clearTextAttribute() { - this.textAttribute = undefined; - } - - /** - * compare with another AbstractVectorSymbology - */ - equals(other: AbstractVectorSymbology) { - if (other instanceof AbstractVectorSymbology) { - return ( - this.fillColorBreakpoint.equals(other.fillColorBreakpoint) && - this.strokeColorBreakpoint.equals(other.strokeColorBreakpoint) && - this.strokeWidth === other.strokeWidth && - this.describesElementFill() === other.describesElementFill() && - this.describesPointsWithRadius() === other.describesPointsWithRadius() && - this.fillColorizer && - this.fillColorizer.equals(other.fillColorizer) && - this.fillColorAttribute && - other.fillColorAttribute && - this.fillColorAttribute === other.fillColorAttribute && - this.strokeColorizer && - this.strokeColorizer.equals(other.strokeColorizer) && - this.strokeColorAttribute && - other.strokeColorAttribute && - this.strokeColorAttribute === other.strokeColorAttribute && - this.strokeDashStyle && - other.strokeDashStyle && - this.strokeDashStyle === other.strokeDashStyle && - this.textColor && - this.textColor.equals(other.textColor) && - this.textStrokeWidth && - other.textStrokeWidth && - this.textStrokeWidth === other.textStrokeWidth && - this.textAttribute && - other.textAttribute && - this.textAttribute === other.textAttribute - ); - } - return false; - } - - protected constructor(config: VectorSymbologyConfig) { - super(); - if (config.fillRGBA) { - this.fillRGBA = Color.fromRgbaLike(config.fillRGBA); - } - if (config.strokeRGBA) { - this.strokeRGBA = Color.fromRgbaLike(config.strokeRGBA); - } - if (config.strokeWidth) { - this.strokeWidth = config.strokeWidth; - } - - if (config.fillColorAttribute) { - this.fillColorAttribute = config.fillColorAttribute; - } - this.fillColorizer = config.fillColorizer ? ColorizerData.fromDict(config.fillColorizer) : ColorizerData.empty(); - - if (config.strokeColorAttribute) { - this.strokeColorAttribute = config.strokeColorAttribute; - } - this.strokeColorizer = config.strokeColorizer ? ColorizerData.fromDict(config.strokeColorizer) : ColorizerData.empty(); - - if (config.strokeDashStyle) { - this.strokeDashStyle = config.strokeDashStyle; - } - - if (config.textAttribute) { - this.textAttribute = config.textAttribute; - } - this.textColor = config.textColor ? Color.fromRgbaLike(config.textColor) : WHITE; - this.textStrokeWidth = config.textStrokeWidth ? config.textStrokeWidth : Math.ceil(config.strokeWidth * 0.1); - } - - toDict(): VectorSymbologyDict { - return { - symbologyType: SymbologyType[this.getSymbologyType()], - fillRGBA: this.fillRGBA.rgbaTuple(), - strokeRGBA: this.strokeRGBA.rgbaTuple(), - strokeWidth: this.strokeWidth, - fillColorAttribute: this.fillColorAttribute, - fillColorizer: this.fillColorizer ? this.fillColorizer.toDict() : undefined, - strokeColorAttribute: this.strokeColorAttribute, - strokeColorizer: this.strokeColorizer, - strokeDashStyle: this.strokeDashStyle, - textAttribute: this.textAttribute, - textColor: this.textColor.rgbaTuple(), - textStrokeWidth: this.textStrokeWidth, - }; - } -} - -/** - * Configuration interface with optional fields for PointSymbology. - */ -export interface PointSymbologyConfig extends VectorSymbologyConfig { - radius?: number; - radiusAttribute?: string; - radiusFactor?: number; - clustered?: boolean; -} - -/** - * Serialization interface for PointSymbology. - */ -interface PointSymbologyDict extends VectorSymbologyDict { - radius: number; - radiusAttribute: string; - radiusFactor: number; - clustered: boolean; -} - -/** - * A class that contains properties for drawing lines - */ -export class LineSymbology extends AbstractVectorSymbology implements VectorSymbologyConfig { - protected constructor(config: VectorSymbologyConfig) { - super(config); - } - - static createSymbology(config: VectorSymbologyConfig): LineSymbology { - return new LineSymbology(config); - } - - describesElementStroke(): boolean { - return true; - } - - describesElementFill(): boolean { - return false; - } - - describesPointsWithRadius(): boolean { - return false; - } - - getSymbologyType(): SymbologyType { - return SymbologyType.COMPLEX_LINE; - } - - clone(): LineSymbology { - return new LineSymbology(this); - } - - toConfig(): LineSymbology { - return this.clone(); - } -} - -/** - * A class that contains properties for drawing vectors such as polygons - */ -export class VectorSymbology extends AbstractVectorSymbology implements VectorSymbologyConfig { - protected constructor(config: VectorSymbologyConfig) { - super(config); - } - - static createSymbology(config: VectorSymbologyConfig): VectorSymbology { - return new VectorSymbology(config); - } - - describesElementStroke(): boolean { - return true; - } - - describesElementFill(): boolean { - return true; - } - - describesPointsWithRadius(): boolean { - return false; - } - - getSymbologyType(): SymbologyType { - return SymbologyType.COMPLEX_VECTOR; - } - - clone(): VectorSymbology { - return new VectorSymbology(this); - } - - toConfig(): VectorSymbologyConfig { - return this.clone(); - } -} - -/** - * A class that contains properties for drawing points - */ -export class PointSymbology extends AbstractVectorSymbology implements PointSymbologyConfig { - radiusAttribute: string = undefined; - radiusFactor = 1.0; - radius: number = DEFAULT_POINT_RADIUS; - clustered = false; - - protected constructor(config: PointSymbologyConfig) { - super(config); - - if (config.radius) { - this.radius = config.radius; - } - - if (config.radiusAttribute) { - this.radiusAttribute = config.radiusAttribute; - } - this.clustered = config.clustered ? config.clustered : false; - this.radiusFactor = config.radiusFactor ? config.radiusFactor : 1.0; - } - - /** - * Creates a PointSymbology where radiusAttribute and textAttribute are set to the strings returned by Mappings cluster operator - */ - static createClusterSymbology(config: PointSymbologyConfig): PointSymbology { - config.radiusAttribute = DEFAULT_POINT_CLUSTER_RADIUS_ATTRIBUTE; - config.textAttribute = DEFAULT_POINT_CLUSTER_TEXT_ATTRIBUTE; - config.clustered = true; - - return PointSymbology.createSymbology(config); - } - - /** - * Creates a default PointSymbology - */ - static createSymbology(config: PointSymbologyConfig): PointSymbology { - return new PointSymbology(config); - } - - getSymbologyType(): SymbologyType { - return SymbologyType.COMPLEX_POINT; - } - - clone(): PointSymbology { - return new PointSymbology(this); - } - - equals(other: AbstractVectorSymbology) { - if (other instanceof PointSymbology) { - return ( - super.equals(other as AbstractVectorSymbology) && - this.radiusAttribute && - other.radiusAttribute && - this.radiusAttribute === other.radiusAttribute - ); - } - return false; - } - - toConfig(): PointSymbologyConfig { - return this.clone(); - } - - describesElementStroke(): boolean { - return true; - } - - describesElementFill(): boolean { - return true; - } - - describesPointsWithRadius(): boolean { - return true; - } - - setRadiusAttributeAndFactor(name: string, factor = 1.0) { - this.radiusAttribute = name; - this.radiusFactor = factor; - } - - clearRadiusAttribute() { - this.radiusAttribute = undefined; - this.radiusFactor = 1.0; - } - - toDict(): PointSymbologyDict { - return { - symbologyType: SymbologyType[SymbologyType.COMPLEX_POINT], - fillRGBA: this.fillRGBA.rgbaTuple(), - strokeRGBA: this.strokeRGBA.rgbaTuple(), - strokeWidth: this.strokeWidth, - fillColorAttribute: this.fillColorAttribute, - fillColorizer: this.fillColorizer ? this.fillColorizer.toDict() : undefined, - strokeColorAttribute: this.strokeColorAttribute, - strokeColorizer: this.strokeColorizer, - strokeDashStyle: this.strokeDashStyle, - radiusAttribute: this.radiusAttribute, - radiusFactor: this.radiusFactor, - radius: this.radius, - textAttribute: this.textAttribute, - textColor: this.textColor.rgbaTuple(), - textStrokeWidth: this.textStrokeWidth, - clustered: this.clustered, - }; - } -} - -/** - * Configuration interface with optional fields for RasterSymbology. - */ -export interface IRasterSymbology extends ISymbology { - opacity?: number; - unit: Unit | UnitDict; -} - -/** - * Serialization interface for RasterSymbology. - */ -export interface RasterSymbologyDict extends SymbologyDict { - opacity: number; - unit: UnitDict; - colorizer?: IColorizerData; - noDataColor?: ColorBreakpointDict; - overflowColor?: ColorBreakpointDict; -} - -/** - * Configuration interface with optional fields for MappingRasterSymbology. - */ -export interface IColorizerRasterSymbology extends IRasterSymbology { - colorizer?: IColorizerData; - noDataColor?: ColorBreakpointDict; - overflowColor?: ColorBreakpointDict; -} - -/** - * The abstract raster symbology class. - */ -export abstract class AbstractRasterSymbology extends AbstractSymbology implements IRasterSymbology { - opacity = 1; - unit: Unit; - - protected constructor(config: IRasterSymbology) { - super(); - if (config.unit instanceof Unit) { - this.unit = config.unit; - } else { - this.unit = Unit.fromDict(config.unit as UnitDict); - } - - if (config.opacity) { - this.opacity = config.opacity; - } - } - - isContinuous() { - return this.unit.interpolation === Interpolation.Continuous; - } - - isDiscrete() { - return this.unit.interpolation === Interpolation.Discrete; - } - - isUnitUnknown() { - return !this.unit || !this.unit.interpolation || this.unit.interpolation === 0; - } - - abstract getSymbologyType(): SymbologyType; - - abstract toConfig(): IRasterSymbology; - - abstract clone(): AbstractRasterSymbology; - - equals(other: AbstractRasterSymbology) { - return this.opacity === other.opacity && this.unit === other.unit; - } - - abstract toDict(): RasterSymbologyDict; -} - -/** - * The raster symbology class with colorizer information, rendered by the mapping backend. - */ -export class MappingRasterSymbology extends AbstractRasterSymbology implements IColorizerRasterSymbology { - colorizer: ColorizerData; - noDataColor: ColorBreakpoint; - overflowColor: ColorBreakpoint; - - /** - * Create the default symbology, with options from config. - */ - static createSymbology(config: IColorizerRasterSymbology) { - return new MappingRasterSymbology(config); - } - - protected constructor(config: IColorizerRasterSymbology) { - super(config); - // TODO: this default colorizer fails if the unit has `undefined` min and max values - this.colorizer = config.colorizer - ? new ColorizerData(config.colorizer) - : Colormap.createColorizerDataWithName('VIRIDIS', config.unit.min, config.unit.max); - this.noDataColor = config.noDataColor - ? new ColorBreakpoint(config.noDataColor) - : new ColorBreakpoint({rgba: TRANSPARENT, value: 'NoData'}); - this.overflowColor = config.overflowColor - ? new ColorBreakpoint(config.overflowColor) - : new ColorBreakpoint({rgba: TRANSPARENT, value: 'Overflow'}); - } - - getSymbologyType(): SymbologyType { - return SymbologyType.MAPPING_COLORIZER_RASTER; - } - - isUnitUnknown(): boolean { - return super.isUnitUnknown(); - } - - toConfig(): IColorizerRasterSymbology { - return this.clone() as IColorizerRasterSymbology; - } - - clone(): MappingRasterSymbology { - return new MappingRasterSymbology(this); - } - - equals(other: AbstractRasterSymbology) { - if (other instanceof MappingRasterSymbology) { - return ( - super.equals(other as AbstractRasterSymbology) && - this.colorizer && - this.colorizer.equals(other.colorizer) && - this.noDataColor && - this.noDataColor.equals(other.noDataColor) && - this.overflowColor && - this.overflowColor.equals(other.overflowColor) - ); - } - return false; - } - - toDict(): RasterSymbologyDict { - return { - symbologyType: SymbologyType[SymbologyType.MAPPING_COLORIZER_RASTER], - opacity: this.opacity, - unit: this.unit.toDict(), - colorizer: this.colorizer.toDict(), - noDataColor: this.noDataColor.toDict(), - overflowColor: this.overflowColor.toDict(), - }; - } - - /** - * generate a colorizer representation for the mapping backend. - */ - mappingColorizerRequestString(): string { - const mcbs: MappingRasterColorizerDict = { - type: this.colorizer.type, - nodata: this.noDataColor.asMappingRasterColorizerBreakpoint(), - default: this.overflowColor.asMappingRasterColorizerBreakpoint(), - breakpoints: this.colorizer.breakpoints.map((br) => br.asMappingRasterColorizerBreakpoint()), - }; - return JSON.stringify(mcbs); - } -} diff --git a/projects/wave-core/src/lib/layout.service.ts b/projects/wave-core/src/lib/layout.service.ts deleted file mode 100644 index 3397aae0..00000000 --- a/projects/wave-core/src/lib/layout.service.ts +++ /dev/null @@ -1,367 +0,0 @@ -import {fromEvent, combineLatest, BehaviorSubject, Observable, ReplaySubject, Subject} from 'rxjs'; -import {debounceTime, distinctUntilChanged, map} from 'rxjs/operators'; -import {Injectable, Type} from '@angular/core'; -import {Config} from './config.service'; - -/** - * Layout settings serialization format. - */ -export interface LayoutDict { - layerListVisible: boolean; - layerDetailViewVisible: boolean; - layerDetailViewTabIndex: number; - layerDetailViewHeightPercentage: number; -} - -export interface SidenavConfig { - component: Type; - keepParent?: boolean; - parent?: SidenavConfig; - config?: {[key: string]: any}; -} - -/** - * A service that keeps track of app layouting options. - */ -@Injectable() -export class LayoutService { - static readonly remInPx: number = parseFloat(getComputedStyle(document.documentElement).fontSize); - - private static _scrollbarWidthPx: number; - - /** - * Is the layer list visible? - */ - private layerListVisible$: BehaviorSubject = new BehaviorSubject(true); - - /** - * Is the data table visible? - */ - private layerDetailViewVisible$: BehaviorSubject = new BehaviorSubject(true); - - /** - * What is the currently visible tab? - */ - private layerDetailViewTabIndex$: BehaviorSubject = new BehaviorSubject(0); - - /** - * What is the height of the layer detail view as a percentage of the available space. - */ - private layerDetailViewHeightPercentage$: BehaviorSubject = new BehaviorSubject(2 / 5); - - /** - * Sidenav content - */ - private sidenavContentComponent$: Subject = new ReplaySubject(1); - - private sidenavContentMaxWidth$: Subject = new ReplaySubject(1); - - constructor(protected config: Config) { - this.setupSidenavWidthStream(); - } - - static scrollbarWidthPx() { - if (!this._scrollbarWidthPx) { - const outer = document.createElement('div'); - outer.style.visibility = 'hidden'; - outer.style.width = '100px'; - // @ts-ignore - outer.style.msOverflowStyle = 'scrollbar'; // needed for WinJS apps - - document.body.appendChild(outer); - - const widthNoScroll = outer.offsetWidth; - // force scrollbars - outer.style.overflow = 'scroll'; - - // add innerdiv - const inner = document.createElement('div'); - inner.style.width = '100%'; - outer.appendChild(inner); - - const widthWithScroll = inner.offsetWidth; - - // remove divs - outer.parentNode.removeChild(outer); - - this._scrollbarWidthPx = widthNoScroll - widthWithScroll; - } - - return this._scrollbarWidthPx; - } - - static getToolbarHeightPx(): number { - const mobileLandscape = window.matchMedia('(max-width: 960px) and (orientation: landscape)').matches; - if (mobileLandscape) { - return 48; - } - - const mobilePortrait = window.matchMedia('(max-width: 600px) and (orientation: portrait)').matches; - if (mobilePortrait) { - return 56; - } - - return 64; - } - - static getLayerDetailViewBarHeightPx(): number { - const mobileLandscape = window.matchMedia('(max-width: 960px) and (orientation: landscape)').matches; - if (mobileLandscape) { - return 2 * LayoutService.remInPx; - } - - const mobilePortrait = window.matchMedia('(max-width: 600px) and (orientation: portrait)').matches; - if (mobilePortrait) { - return 2.5 * LayoutService.remInPx; - } - - const borderSizePx = 1; - - return 3 * LayoutService.remInPx + borderSizePx; - } - - /** - * Calculate the height of the data table. - */ - private static calculateLayerDetailViewHeight(layerDetailViewHeightPercentage: number, totalAvailableHeight: number): number { - return Math.max(Math.ceil(layerDetailViewHeightPercentage * totalAvailableHeight), LayoutService.getLayerDetailViewBarHeightPx()); - } - - /** - * Calculate the height of the map. - */ - private static calculateMapHeight(layerDetailViewHeightPercentage: number, totalAvailableHeight: number): number { - const layerDetailViewHeight = LayoutService.calculateLayerDetailViewHeight(layerDetailViewHeightPercentage, totalAvailableHeight); - return totalAvailableHeight - layerDetailViewHeight; - } - - getSidenavWidthStream(): Observable { - return this.sidenavContentMaxWidth$; - } - - /** - * Which component to show in the sidenav? - */ - getSidenavContentComponentStream(): Observable { - return this.sidenavContentComponent$.pipe(distinctUntilChanged()); - } - - /** - * Set the new Component to show in the sidenav - */ - setSidenavContentComponent(sidenavConfig: SidenavConfig) { - this.sidenavContentComponent$.next(sidenavConfig); - } - - /** - * Is the layer list visible in the component? - */ - getLayerListVisibility(): boolean { - return this.layerListVisible$.value; - } - - /** - * Is the layer list visible in the component? - */ - getLayerListVisibilityStream(): Observable { - return this.layerListVisible$; - } - - /** - * Sets the visibility of the layer list. - */ - setLayerListVisibility(visible: boolean) { - this.layerListVisible$.next(visible); - } - - /** - * Toggles the visibility of the layer list. - */ - toggleLayerListVisibility() { - this.setLayerListVisibility(!this.layerListVisible$.value); - } - - /** - * Is the layer detail view visible? - */ - getLayerDetailViewVisibilityStream(): Observable { - return this.layerDetailViewVisible$; - } - - /** - * Is the layer detail view visible? - */ - getLayerDetailViewVisibility(): boolean { - return this.layerDetailViewVisible$.value; - } - - /** - * Sets the visibility of the layer detail view. - */ - setLayerDetailViewVisibility(visible: boolean) { - this.layerDetailViewVisible$.next(visible); - } - - /** - * Toggles the visibility of the layer detail view. - */ - toggleLayerDetailViewVisibility() { - this.setLayerDetailViewVisibility(!this.layerDetailViewVisible$.value); - } - - /** - * What is the current tab index? - */ - getLayerDetailViewTabIndexStream(): Observable { - return this.layerDetailViewTabIndex$; - } - - /** - * What is the current tab index? - */ - getLayerDetailViewTabIndex(): number { - return this.layerDetailViewTabIndex$.value; - } - - /** - * Set the current tab index. - */ - setLayerDetailViewTabIndex(index: number) { - // ignore call if it is the same index. - if (this.layerDetailViewTabIndex$.value === index) { - return; - } - - if (index < 0) { - index = 0; // repair index - } - - this.layerDetailViewTabIndex$.next(index); - } - - /** - * Sets the percentage of the vertical viewport that the data table covers. - */ - setLayerDetailViewHeightPercentage(percentage: number) { - if (percentage < 0 || percentage > 1) { - throw Error('The data table percentage value must be between 0 and 1.'); - } - - this.layerDetailViewHeightPercentage$.next(percentage); - } - - /** - * Calculate the height of the data table. - */ - getLayerDetailViewHeight(totalAvailableHeight: number): number { - return LayoutService.calculateLayerDetailViewHeight( - this.layerDetailViewVisible$.value ? this.layerDetailViewHeightPercentage$.value : 0, - totalAvailableHeight, - ); - } - - /** - * Calculate the height of the data table. - */ - getLayerDetailViewStream(totalAvailableHeight$: Observable): Observable { - return combineLatest([this.layerDetailViewHeightPercentage$, totalAvailableHeight$, this.layerDetailViewVisible$]).pipe( - map(([layerDetailViewHeightPercentage, totalAvailableHeight, layerDetailViewVisible]): number => { - return LayoutService.calculateLayerDetailViewHeight( - layerDetailViewVisible ? layerDetailViewHeightPercentage : 0, - totalAvailableHeight, - ); - }), - ); - } - - /** - * Calculate the height of the map. - */ - getMapHeight(totalAvailableHeight: number): number { - return LayoutService.calculateMapHeight( - this.layerDetailViewVisible$.value ? this.layerDetailViewHeightPercentage$.value : 0, - totalAvailableHeight, - ); - } - - /** - * Calculate the height of the data table. - */ - getMapHeightStream(totalAvailableHeight$: Observable): Observable { - return combineLatest(this.layerDetailViewHeightPercentage$, totalAvailableHeight$, this.layerDetailViewVisible$).pipe( - map(([layerDetailViewHeightPercentage, totalAvailableHeight, layerDetailViewVisible]): number => { - return LayoutService.calculateMapHeight(layerDetailViewVisible ? layerDetailViewHeightPercentage : 0, totalAvailableHeight); - }), - ); - } - - getLayoutDict(): LayoutDict { - return { - layerListVisible: this.getLayerListVisibility(), - layerDetailViewVisible: this.getLayerDetailViewVisibility(), - layerDetailViewTabIndex: this.getLayerDetailViewTabIndex(), - layerDetailViewHeightPercentage: this.layerDetailViewHeightPercentage$.getValue(), - }; - } - - getLayoutDictStream(): Observable { - return combineLatest([ - this.layerListVisible$, - this.layerDetailViewVisible$, - this.layerDetailViewTabIndex$, - this.layerDetailViewHeightPercentage$, - ]).pipe( - map(([layerListVisible, layerDetailViewVisible, layerDetailViewTabIndex, layerDetailViewHeightPercentage]) => { - return { - layerListVisible, - layerDetailViewVisible, - layerDetailViewTabIndex, - layerDetailViewHeightPercentage, - }; - }), - ); - } - - setLayoutDict(dict: LayoutDict) { - if (typeof dict.layerListVisible === 'boolean') { - this.setLayerListVisibility(dict.layerListVisible); - } - if (typeof dict.layerDetailViewVisible === 'boolean') { - this.setLayerDetailViewVisibility(dict.layerDetailViewVisible); - } - if (typeof dict.layerDetailViewTabIndex === 'number') { - this.setLayerDetailViewTabIndex(dict.layerDetailViewTabIndex); - } - if (typeof dict.layerDetailViewHeightPercentage === 'number') { - this.setLayerDetailViewHeightPercentage(dict.layerDetailViewHeightPercentage); - } - } - - /** - * Initialize and update the sidenav INNER width stream - */ - private setupSidenavWidthStream() { - function getWidth(): number { - const sidenavComponent = document.getElementsByTagName('mat-sidenav')[0]; - const sidenavStyle = window.getComputedStyle(sidenavComponent); - const widthString = sidenavStyle.width; - - if (widthString.indexOf('px') === widthString.length - 2) { - return parseFloat(widthString.substr(0, widthString.length - 2)) - 4 * LayoutService.remInPx; - } else { - throw new Error('sidenav width must be a `px` value'); - } - } - - // this timeout prevents calling the `getWidth` function before the DOM is initialized - setTimeout(() => { - fromEvent(window, 'resize') - .pipe(debounceTime(this.config.DELAYS.DEBOUNCE)) - .subscribe(() => { - this.sidenavContentMaxWidth$.next(getWidth()); - }); - - this.sidenavContentMaxWidth$.next(getWidth()); - }); - } -} diff --git a/projects/wave-core/src/lib/logo.component.ts b/projects/wave-core/src/lib/logo.component.ts deleted file mode 100644 index ae3592d0..00000000 --- a/projects/wave-core/src/lib/logo.component.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {Component} from '@angular/core'; - -@Component({ - selector: 'wave-vat-logo', - template: `

VAT

`, - styles: [ - ` - h1 { - background: #fff; - height: 3rem; - padding: 0.5rem; - border-radius: 3px; - margin: calc((82px - 4rem) / 2) auto; - } - - .blue { - color: #3258a1; - } - - .light-blue { - color: #3cace4; - } - - .green { - color: #8cb74c; - } - `, - ], -}) -export class VatLogoComponent {} diff --git a/projects/wave-core/src/lib/map/map-container/map-container.component.html b/projects/wave-core/src/lib/map/map-container/map-container.component.html deleted file mode 100644 index 88926088..00000000 --- a/projects/wave-core/src/lib/map/map-container/map-container.component.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/projects/wave-core/src/lib/map/map-container/map-container.component.scss b/projects/wave-core/src/lib/map/map-container/map-container.component.scss deleted file mode 100644 index 97530fe7..00000000 --- a/projects/wave-core/src/lib/map/map-container/map-container.component.scss +++ /dev/null @@ -1,9 +0,0 @@ -.map ::ng-deep figure { - background: black; - overflow: auto; - height: 100%; -} - -mat-grid-list { - height: 100%; -} diff --git a/projects/wave-core/src/lib/map/map-container/map-container.component.ts b/projects/wave-core/src/lib/map/map-container/map-container.component.ts deleted file mode 100644 index 02c7ce98..00000000 --- a/projects/wave-core/src/lib/map/map-container/map-container.component.ts +++ /dev/null @@ -1,654 +0,0 @@ -import {combineLatest, Observable, Subscription} from 'rxjs'; -import {first, map as rxMap} from 'rxjs/operators'; - -import { - AfterViewInit, - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - ContentChildren, - ElementRef, - Input, - OnChanges, - OnDestroy, - QueryList, - SimpleChange, - ViewChild, - ViewChildren, -} from '@angular/core'; - -import OlMap from 'ol/Map'; -import OlView from 'ol/View'; -import OlCollection from 'ol/Collection'; -import OlFeature from 'ol/Feature'; - -import OlLayerImage from 'ol/layer/Image'; -import OlLayer from 'ol/layer/Layer'; -import OlLayerTile from 'ol/layer/Tile'; -import OlLayerVector from 'ol/layer/Vector'; - -import OlSource from 'ol/source/Source'; -import OlSourceOSM from 'ol/source/OSM'; -import OlTileWmsSource from 'ol/source/TileWMS'; -import OlSourceVector from 'ol/source/Vector'; -import XYZ from 'ol/source/XYZ'; -import OlImageStatic from 'ol/source/ImageStatic'; - -import OlGeometryType from 'ol/geom/GeometryType'; -import OlGeomPoint from 'ol/geom/Point'; -import OlFormatGeoJSON from 'ol/format/GeoJSON'; - -import OlStyleFill from 'ol/style/Fill'; -import OlStyleStroke from 'ol/style/Stroke'; -import OlStyleStyle from 'ol/style/Style'; - -import OlInteractionDraw from 'ol/interaction/Draw'; -import OlInteractionSelect from 'ol/interaction/Select'; -import {SelectEvent as OlInteractionSelectEvent} from 'ol/interaction/Select'; - -import {MapLayerComponent} from '../map-layer.component'; - -import {Projection, Projections} from '../../operators/projection.model'; -import {AbstractVectorSymbology, AbstractSymbology} from '../../layers/symbology/symbology.model'; -import {Layer} from '../../layers/layer.model'; -import {LayerService} from '../../layers/layer.service'; -import {ProjectService} from '../../project/project.service'; -import {Extent, MapService} from '../map.service'; -import {Config} from '../../config.service'; -import {StyleCreator} from '../style-creator'; -import {LayoutService} from '../../layout.service'; -import {MatGridList, MatGridTile} from '@angular/material/grid-list'; - -type MapLayer = MapLayerComponent>; - -const DEFAULT_ZOOM_LEVEL = 2; -const MIN_ZOOM_LEVEL = 0; -const MAX_ZOOM_LEVEL = 28; - -/** - * The `wave-map-container` component encapsulates openLayers maps. - * It displays `wave-map-layer` components as child components, i.e., either layers on a single map or a grid of maps. - */ -@Component({ - selector: 'wave-map-container', - templateUrl: 'map-container.component.html', - styleUrls: ['map-container.component.scss'], - queries: { - contentChildren: new ContentChildren(MapLayerComponent), - }, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class MapContainerComponent implements AfterViewInit, OnChanges, OnDestroy { - /** - * display a grid of maps or all layers on a single map - */ - @Input() grid = true; // TODO: false; - - @ViewChild(MatGridList, {read: ElementRef, static: true}) gridListElement!: ElementRef; - @ViewChildren(MatGridTile, {read: ElementRef}) mapContainers!: QueryList; - - /** - * These are the layers from the layer list (as dom elements in the template) - */ - @ContentChildren(MapLayerComponent) mapLayersRaw!: QueryList; - mapLayers: Array = []; // filtered - - numberOfRows = 1; - numberOfColumns = 1; - rowHeight = 'fit'; - - private projection$: Observable = this.projectService.getProjectionStream(); - - private maps: Array; - private view: OlView; - private backgroundLayerSource: OlSource; - private backgroundLayers: Array = []; - - private selectedOlLayer: OlLayer = undefined; - private userSelect: OlInteractionSelect; - - private drawInteractionSource: OlSourceVector; - private drawType: OlGeometryType; - private drawInteractions: Array = []; - private drawInteractionLayers: Array = []; - - private subscriptions: Array = []; - - /** - * Create the component and inject several dependencies via DI. - */ - constructor( - private config: Config, - private changeDetectorRef: ChangeDetectorRef, - private mapService: MapService, - private layerService: LayerService, - private layoutService: LayoutService, - private projectService: ProjectService, - ) { - // set dummy maps so that they are not uninitialized - this.view = new OlView({ - zoom: DEFAULT_ZOOM_LEVEL, - }); - this.maps = [ - new OlMap({ - view: this.view, - }), - ]; - } - - ngOnDestroy() { - this.subscriptions.forEach((s) => s.unsubscribe()); - } - - ngAfterViewInit() { - this.projection$.pipe(first()).subscribe((projection) => { - this.maps.forEach((map) => map.setTarget(undefined)); // initially reset all DOM bindings - - this.initOpenlayersMap(projection); - - // since all viewports are linked and there will always be the first map, we link the event only to map 0 - this.maps[0].on('moveend', (_event) => this.emitViewportSize()); - - this.initUserSelect(); - - this.subscriptions.push( - combineLatest(this.mapLayersRaw.changes, this.projection$) - .pipe(rxMap(([_changes, newProjection]) => newProjection)) - .subscribe((newProjection: Projection) => { - this.redrawLayers(newProjection); - }), - ); - }); - } - - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { - for (const propName in changes) { - if (propName === 'grid') { - this.projection$.pipe(first()).subscribe((projection) => this.redrawLayers(projection)); - } - } - } - - /** - * Notify the map that the container has resized. - */ - resize() { - setTimeout(() => this.projection$.pipe(first()).subscribe((projection) => this.redrawLayers(projection))); - } - - /** - * Increases the zoom level if it is not larger than the maximum zoom level - */ - zoomIn() { - if (this.view.getZoom() < MAX_ZOOM_LEVEL) { - this.view.adjustZoom(1); - } - } - - /** - * Decreases the zoom level if it is not smaller than the minimum zoom level - */ - zoomOut() { - if (this.view.getZoom() > MIN_ZOOM_LEVEL) { - this.view.adjustZoom(-1); - } - } - - /** - * Zoom to and focus a bounding box - */ - zoomTo(boundingBox: Extent) { - this.view.fit(boundingBox, { - nearest: true, - maxZoom: MAX_ZOOM_LEVEL, - }); - } - - /** - * Enable user input (hand drawn) for the map - */ - public startDrawInteraction(drawType: OlGeometryType) { - if (this.isDrawInteractionAttached()) { - throw new Error('only one draw interaction can be active!'); - } - - this.drawType = drawType; - this.drawInteractionSource = new OlSourceVector({wrapX: false}); - - this.reattachDrawInteractions(); - } - - /** - * Indicator if the map currently has a source for user input (hand drawn) - */ - public isDrawInteractionAttached(): boolean { - return !!this.drawInteractionSource; - } - - /** - * Disable user input (hand drawn) for the map and return the result - */ - public endDrawInteraction(): OlSourceVector { - if (!this.isDrawInteractionAttached()) { - console.error('no interaction or layer active!'); - return undefined; - } - - const source = this.drawInteractionSource; - - this.drawInteractionSource = undefined; - - this.reattachDrawInteractions(); - - return source; - } - - private createDrawInteractionLayer(): OlLayerVector { - return new OlLayerVector({ - source: this.drawInteractionSource, - }); - } - - private createDrawInteraction(): OlInteractionDraw { - return new OlInteractionDraw({ - source: this.drawInteractionSource, - type: this.drawType, - }); - } - - private reattachDrawInteractions() { - // remove layers - this.drawInteractionLayers.forEach((layer, index) => { - if (index < this.maps.length) { - this.maps[index].removeLayer(layer); - } - layer.setMap(undefined); - }); - this.drawInteractionLayers.length = 0; - - // remove interactions - this.drawInteractions.forEach((interaction, index) => { - if (index < this.maps.length) { - this.maps[index].removeInteraction(interaction); - } - interaction.setMap(undefined); - }); - this.drawInteractions.length = 0; - - // reattach - if (this.isDrawInteractionAttached()) { - this.maps.forEach((map) => { - const drawInteractionLayer = this.createDrawInteractionLayer(); - this.drawInteractionLayers.push(drawInteractionLayer); - map.addLayer(drawInteractionLayer); - - const drawInteraction = this.createDrawInteraction(); - this.drawInteractions.push(drawInteraction); - map.addInteraction(drawInteraction); - }); - } - } - - /** - * Force a redraw for each map layer - */ - public layerForcesRedraw() { - this.projection$.pipe(first()).subscribe((projection) => this.redrawLayers(projection)); - } - - private calculateGrid() { - const numberOfLayers = this.desiredNumberOfMaps(); - - const containerWidth = this.gridListElement.nativeElement.clientWidth; - const containerHeight = this.gridListElement.nativeElement.clientHeight; - const ratio = containerWidth / containerHeight; - - let rows = 1; - let columns = 1; - - // this is a heuristic of calculating the division of rows and columns for displaying the layers - while (rows * columns < numberOfLayers) { - if (columns <= rows * ratio) { - columns += 1; - } else { - rows += 1; - } - } - - while ((columns - 1) * rows >= numberOfLayers) { - // reduce unnecessary columns - columns -= 1; - } - - this.numberOfRows = columns; - this.numberOfColumns = columns; - } - - private initOpenlayersMap(projection: Projection) { - this.maps = [ - new OlMap({ - controls: [], - logo: false, - loadTilesWhileAnimating: true, // TODO: check if moved to layer - loadTilesWhileInteracting: true, // TODO: check if moved to layer - }), - ]; - this.createAndSetView(projection); - } - - private initUserSelect() { - this.userSelect = new OlInteractionSelect({ - layers: (layerCandidate: OlLayer) => layerCandidate === this.selectedOlLayer, - }); - this.userSelect.setActive(false); - - this.subscriptions.push( - this.layerService.getSelectedLayerStream().subscribe((selectedLayer) => { - // reset old selection - this.userSelect.getFeatures().forEach((feature) => feature.setStyle(undefined)); - this.userSelect.getFeatures().clear(); - - const filteredLayers = this.mapLayers.filter((mapLayer) => mapLayer.layer === selectedLayer); - this.selectedOlLayer = filteredLayers.length ? filteredLayers[0].mapLayer : undefined; - this.userSelect.setActive(!!this.selectedOlLayer); - - this.attachUserSelectToMap(); - }), - ); - - this.userSelect.on('select', (selectEvent: OlInteractionSelectEvent) => { - const selectedLayerSymbology = this.layerService.getSelectedLayer().symbology; - - if (selectedLayerSymbology instanceof AbstractVectorSymbology) { - const highlightSymbology = StyleCreator.createHighlightSymbology(selectedLayerSymbology); - const highlightStyle = StyleCreator.fromVectorSymbology(highlightSymbology); - selectEvent.selected.forEach((feature) => feature.setStyle(highlightStyle)); - } - - selectEvent.deselected.forEach((feature) => feature.setStyle(undefined)); - - this.layerService.updateSelectedFeatures( - selectEvent.selected.map((feature) => feature.getId()), - selectEvent.deselected.map((feature) => feature.getId()), - ); - }); - - this.subscriptions.push( - this.layerService.getSelectedFeaturesStream().subscribe((selectedFeatures) => { - const newSelection = new OlCollection(); - this.userSelect.getFeatures().forEach((feature) => { - if (selectedFeatures.remove && selectedFeatures.remove.contains(feature.getId())) { - newSelection.push(feature); - feature.setStyle(undefined); - } - }); - - newSelection.forEach((feature) => this.userSelect.getFeatures().remove(feature)); - - const selectedLayer = this.layerService.getSelectedLayer(); - - if (!selectedLayer || !this.selectedOlLayer) { - return; - } - - if (this.selectedOlLayer instanceof OlLayerVector) { - const highlightSymbology = StyleCreator.createHighlightSymbology(selectedLayer.symbology as AbstractVectorSymbology); - const highlightStyle = StyleCreator.fromVectorSymbology(highlightSymbology); - - this.selectedOlLayer - .getSource() - .getFeatures() - .forEach((feature) => { - if (selectedFeatures.add && selectedFeatures.add.contains(feature.getId())) { - if (this.userSelect.getFeatures().getArray().indexOf(feature) === -1) { - this.userSelect.getFeatures().push(feature); - // todo: add resolution as third parameter - feature.setStyle(highlightStyle); - } - } - }); - } - }), - ); - } - - private attachUserSelectToMap() { - if (!this.userSelect) { - // called too early - return; - } - - let map; - if (!this.selectedOlLayer) { - map = undefined; - } else if (this.maps.length === 1) { - // mono map, no choice - map = this.maps[0]; - } else { - const selectedLayerIndex = this.mapLayers.map((layer) => layer.mapLayer).indexOf(this.selectedOlLayer); - if (selectedLayerIndex >= 0) { - const inverseIndex = this.maps.length - selectedLayerIndex - 1; - map = this.maps[inverseIndex]; - } else { - map = undefined; // actually, something went wrong - } - } - - const oldMap = this.userSelect.getMap(); - if (map !== oldMap) { - if (oldMap) { - oldMap.removeInteraction(this.userSelect); - } - this.userSelect.setMap(map); - if (map) { - map.addInteraction(this.userSelect); - } - } - } - - private redrawLayers(projection: Projection) { - this.mapLayers = this.mapLayersRaw.filter((mapLayer) => mapLayer.layer.visible); - - this.calculateGrid(); - this.changeDetectorRef.detectChanges(); - - if (this.grid && this.mapLayers.length && this.mapContainers.length !== this.mapLayers.length) { - console.error('race condition!'); - } - - while (this.maps.length > this.desiredNumberOfMaps()) { - const removedMap = this.maps.pop(); - removedMap.setTarget(undefined); // remove DOM reference to map - } - while (this.maps.length < this.desiredNumberOfMaps()) { - // enlarge maps if necessary - this.maps.push( - new OlMap({ - controls: [], - logo: false, - view: this.view, - loadTilesWhileAnimating: true, // TODO: check if moved to layer - loadTilesWhileInteracting: true, // TODO: check if moved to layer - }), - ); - } - - this.mapContainers.forEach((mapContainer, i) => { - const mapTarget: HTMLElement = mapContainer.nativeElement.children[0]; - this.maps[i].setTarget(mapTarget); - this.maps[i].updateSize(); - }); - - const oldProjection = this.view ? this.view.getProjection() : undefined; - const projectionChanged = oldProjection !== projection.getOpenlayersProjection(); - - if (projectionChanged) { - this.createAndSetView(projection); - } - - if (projectionChanged || !this.backgroundLayerSource) { - this.backgroundLayerSource = this.createBackgroundLayerSource(projection); - - this.backgroundLayers.length = 0; - } - - if (this.backgroundLayers.length > this.desiredNumberOfMaps()) { - // reduce background layers if necessary - this.backgroundLayers.length = this.desiredNumberOfMaps(); - } - while (this.backgroundLayers.length < this.desiredNumberOfMaps()) { - // create background layers if necessary - this.backgroundLayers.push(this.createBackgroundLayer(projection)); - } - - this.maps.forEach((map, index) => { - map.getLayers().clear(); - map.getLayers().push(this.backgroundLayers[index]); - - if (this.grid) { - if (this.mapLayers.length) { - const inverseIndex = this.mapLayers.length - index - 1; - map.getLayers().push(this.mapLayers[inverseIndex].mapLayer); - } - } else { - this.mapLayers.forEach((layerComponent) => map.addLayer(layerComponent.mapLayer)); - } - }); - - this.reattachDrawInteractions(); - - this.attachUserSelectToMap(); - } - - private desiredNumberOfMaps(): number { - return this.grid ? Math.max(this.mapLayers.length, 1) : 1; - } - - private createAndSetView(projection: Projection) { - const zoomLevel = this.view ? this.view.getZoom() : DEFAULT_ZOOM_LEVEL; - - let newCenterPoint: OlGeomPoint; - if (this.view && this.view.getCenter()) { - const oldCenterPoint = new OlGeomPoint(this.view.getCenter()); - newCenterPoint = oldCenterPoint.transform(this.view.getProjection(), projection.getOpenlayersProjection()) as OlGeomPoint; - } else { - newCenterPoint = new OlGeomPoint([0, 0]); - } - - this.view = new OlView({ - projection: projection.getOpenlayersProjection(), - center: newCenterPoint.getCoordinates(), - minZoom: MIN_ZOOM_LEVEL, - maxZoom: MAX_ZOOM_LEVEL, - zoom: zoomLevel, - enableRotation: false, - constrainResolution: true, // no intermediate zoom levels - multiWorld: true, - }); - this.maps.forEach((map) => map.setView(this.view)); - - this.emitViewportSize(); - - // get resolution changes - this.view.on('change:resolution', () => { - // remove selected features on resolution change - this.layerService.updateSelectedFeatures([], this.layerService.getSelectedFeatures().selected.toArray()); - }); - } - - private emitViewportSize() { - this.mapService.setViewportSize({ - extent: this.view.calculateExtent(this.maps[0].getSize()), - resolution: this.view.getResolution(), - maxExtent: this.view.getProjection().getExtent(), - }); - } - - private createBackgroundLayer(projection: Projection): OlLayerImage { - switch (this.config.MAP.BACKGROUND_LAYER) { - case 'OSM': - if (projection === Projections.WEB_MERCATOR) { - return new OlLayerTile({ - source: this.backgroundLayerSource, - wrapX: false, - }); - } else { - return new OlLayerImage({ - // placeholder image - source: this.backgroundLayerSource, - }); - } - case 'countries': // eslint-disable-line no-fallthrough, , - return new OlLayerVector({ - source: this.backgroundLayerSource, - style: (feature: OlFeature, _resolution: number): OlStyleStyle => { - if (feature.getId() === 'BACKGROUND') { - return new OlStyleStyle({ - fill: new OlStyleFill({ - color: '#ADD8E6', - }), - }); - } else { - return new OlStyleStyle({ - stroke: new OlStyleStroke({ - color: 'rgba(0, 0, 0, 1)', - width: 1, - }), - fill: new OlStyleFill({ - color: 'rgba(210, 180, 140, 1)', - }), - }); - } - }, - }); - case 'hosted': - return new OlLayerTile({ - source: this.backgroundLayerSource, - }); - case 'XYZ': - return new OlLayerTile({ - source: this.backgroundLayerSource, - }); - default: - throw Error('Unknown Background Layer Name'); - } - } - - private createBackgroundLayerSource(projection: Projection): OlSource { - switch (this.config.MAP.BACKGROUND_LAYER) { - case 'OSM': - if (projection === Projections.WEB_MERCATOR) { - return new OlSourceOSM(); - } else { - return new OlImageStatic({ - imageExtent: [0, 0, 0, 0], - }); - } - case 'countries': // eslint-disable-line no-fallthrough - return new OlSourceVector({ - url: 'assets/countries.geo.json', - format: new OlFormatGeoJSON(), - }); - case 'hosted': - return new OlTileWmsSource({ - url: this.config.MAP.HOSTED_BACKGROUND_SERVICE, - params: { - layers: this.config.MAP.HOSTED_BACKGROUND_LAYER_NAME, - projection: projection.getCode(), - version: this.config.MAP.HOSTED_BACKGROUND_SERVICE_VERSION, - }, - wrapX: false, - projection: projection.getCode(), - crossOrigin: 'anonymous', - }); - case 'XYZ': - return new XYZ({ - url: this.config.MAP.BACKGROUND_LAYER_URL, - wrapX: false, - projection: projection.getCode(), - }); - default: - throw Error('Unknown Background Layer Name'); - } - } -} diff --git a/projects/wave-core/src/lib/map/map-layer.component.ts b/projects/wave-core/src/lib/map/map-layer.component.ts deleted file mode 100644 index 501396d1..00000000 --- a/projects/wave-core/src/lib/map/map-layer.component.ts +++ /dev/null @@ -1,330 +0,0 @@ -import {ChangeDetectionStrategy, Component, Directive, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core'; -import {Subscription} from 'rxjs'; - -import {Layer as OlLayer, Tile as OlLayerTile, Vector as OlLayerVector} from 'ol/layer'; -import {Source as OlSource, Tile as OlTileSource, TileWMS as OlTileWmsSource, Vector as OlVectorSource} from 'ol/source'; - -import {AbstractSymbology, AbstractVectorSymbology, MappingRasterSymbology} from '../layers/symbology/symbology.model'; - -import {StyleCreator} from './style-creator'; -import {Layer, LayerChanges, RasterData, RasterLayer, VectorData, VectorLayer} from '../layers/layer.model'; -import {MappingQueryService} from '../queries/mapping-query.service'; -import {Config} from '../config.service'; -import {ProjectService} from '../project/project.service'; -import {LoadingState} from '../project/loading-state.model'; -import {Time} from '../time/time.model'; -import {Projection} from '../operators/projection.model'; - -/** - * The `ol-layer` component represents a single layer object of open layers. - */ -@Directive() -// eslint-disable-next-line @angular-eslint/directive-class-suffix -export abstract class MapLayerComponent
    > { - /** - * A raster or vector layer - */ - @Input() layer: L; - - /** - * Event emitter that forces a redraw of the map. - * Must be connected to the map component. - */ - @Output() mapRedraw = new EventEmitter(); - - protected source: OS; - protected _mapLayer: OL; - - /** - * Setup of DI - */ - protected constructor(protected projectService: ProjectService) {} - - /** - * Return the open layers layer element that displays our layer type - */ - get mapLayer(): OL { - return this._mapLayer; - } - - /** - * Return the extent of the layer in map units - */ - abstract getExtent(): [number, number, number, number]; -} - -/** - * The vector layer abstraction for a map layer - */ -@Directive() -export abstract class OlVectorLayerComponent - extends MapLayerComponent> - implements OnInit, OnDestroy { - private dataSubscription: Subscription; - private layerChangesSubscription: Subscription; - - protected constructor(protected projectService: ProjectService) { - super(projectService); - this.source = new OlVectorSource({wrapX: false}); - this._mapLayer = new OlLayerVector({ - source: this.source, - updateWhileAnimating: true, - }); - } - - ngOnInit() { - this.dataSubscription = this.projectService.getLayerDataStream(this.layer).subscribe((x: VectorData) => { - this.source.clear(); // TODO: check if this is needed always... - if (!(x === null || x === undefined)) { - this.source.addFeatures(x.data); - } - this.updateOlLayer({symbology: this.layer.symbology}); // FIXME: HACK until data is a part of a layer - }); - - this.layerChangesSubscription = this.projectService - .getLayerChangesStream(this.layer) - .subscribe((changes: LayerChanges) => { - this.updateOlLayer(changes); - }); - } - - ngOnDestroy() { - if (this.dataSubscription) { - this.dataSubscription.unsubscribe(); - } - if (this.layerChangesSubscription) { - this.layerChangesSubscription.unsubscribe(); - } - } - - getExtent() { - return this.source.getExtent(); - } - - private updateOlLayer(changes: LayerChanges) { - if (changes.visible !== undefined) { - this.mapLayer.setVisible(this.layer.visible); - this.mapRedraw.emit(); - } - - if (changes.symbology) { - const style = StyleCreator.fromVectorSymbology(this.layer.symbology); - this.mapLayer.setStyle(style); - } - } -} - -/** - * This component reflects a point layer on the map - */ -@Component({ - selector: 'wave-ol-point-layer', - template: '', - providers: [{provide: MapLayerComponent, useExisting: OlPointLayerComponent}], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class OlPointLayerComponent extends OlVectorLayerComponent implements OnInit, OnDestroy { - constructor(protected projectService: ProjectService) { - super(projectService); - } -} - -/** - * This component reflects a point line on the map - */ -@Component({ - selector: 'wave-ol-line-layer', - template: '', - providers: [{provide: MapLayerComponent, useExisting: OlLineLayerComponent}], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class OlLineLayerComponent extends OlVectorLayerComponent implements OnInit, OnDestroy { - constructor(protected projectService: ProjectService) { - super(projectService); - } -} - -/** - * This component reflects a polygon layer on the map - */ -@Component({ - selector: 'wave-ol-polygon-layer', - template: '', - providers: [{provide: MapLayerComponent, useExisting: OlPolygonLayerComponent}], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class OlPolygonLayerComponent extends OlVectorLayerComponent implements OnInit, OnDestroy { - constructor(protected projectService: ProjectService) { - super(projectService); - } -} - -/** - * This component reflects a raster layer on the map - */ -@Component({ - selector: 'wave-ol-raster-layer', - template: '', - providers: [{provide: MapLayerComponent, useExisting: OlRasterLayerComponent}], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class OlRasterLayerComponent - extends MapLayerComponent> - implements OnInit, OnDestroy { - private dataSubscription: Subscription; - private layerChangesSubscription: Subscription; - private timeSubscription: Subscription; - - private projection: Projection; - private time: Time; - - constructor(protected projectService: ProjectService, protected mappingQueryService: MappingQueryService, private config: Config) { - super(projectService); - } - - ngOnInit() { - this.dataSubscription = this.projectService.getLayerDataStream(this.layer).subscribe((rasterData: RasterData) => { - if (!rasterData) { - return; - } - - this.updateTime(rasterData.time); - this.updateProjection(rasterData.projection); - - if (!this.source) { - this.initializeOrReplaceOlSource(); - } - - if (this.config.MAP.REFRESH_LAYERS_ON_CHANGE) { - this.source.refresh(); - } - }); - - this.layerChangesSubscription = this.projectService - .getLayerChangesStream(this.layer) - .subscribe((changes: LayerChanges) => { - this.updateOlLayer(changes); - if (this.config.MAP.REFRESH_LAYERS_ON_CHANGE) { - this.source.refresh(); - } - }); - } - - ngOnDestroy() { - if (this.dataSubscription) { - this.dataSubscription.unsubscribe(); - } - if (this.layerChangesSubscription) { - this.layerChangesSubscription.unsubscribe(); - } - if (this.timeSubscription) { - this.timeSubscription.unsubscribe(); - } - } - - private updateOlLayer(changes: LayerChanges) { - if (this.source === undefined || this._mapLayer === undefined) { - return; - } - - if (changes.visible !== undefined) { - this._mapLayer.setVisible(this.layer.visible); - this.mapRedraw.emit(); - } - if (changes.symbology !== undefined) { - this._mapLayer.setOpacity(this.layer.symbology.opacity); - this.source.updateParams({ - colors: this.layer.symbology.mappingColorizerRequestString(), - }); - } - if (changes.operator !== undefined) { - this.initializeOrReplaceOlSource(); - } - } - - private updateProjection(p: Projection) { - if (!this.projection || this.source.getProjection().getCode() !== this.projection.getCode()) { - this.projection = p; - this.updateOlLayerProjection(); - } - } - - private updateOlLayerProjection() { - // there is no way to change the projection of a layer. // TODO: check newer OL versions for this - this.initializeOrReplaceOlSource(); - } - - private updateOlLayerTime() { - if (this.source) { - this.source.updateParams({ - time: this.time.asRequestString(), - colors: this.layer.symbology.mappingColorizerRequestString(), - }); - } - } - - private updateTime(t: Time) { - if (this.time === undefined || !t.isSame(this.time)) { - this.time = t; - this.updateOlLayerTime(); - } - } - - private initializeOrReplaceOlSource() { - this.source = new OlTileWmsSource({ - url: this.createWmsQueryUrl(), - params: { - time: this.time.asRequestString(), - colors: this.layer.symbology.mappingColorizerRequestString(), - }, - projection: this.projection.getCode(), - wrapX: false, - }); - - this.addStateListenersToOlSource(); - this.initializeOrUpdateOlMapLayer(); - } - - private createWmsQueryUrl(): string { - return this.mappingQueryService.getWMSQueryUrl({ - operator: this.layer.operator, - time: this.time, - projection: this.projection, - }); - } - - private initializeOrUpdateOlMapLayer() { - if (this._mapLayer) { - this._mapLayer.setSource(this.source); - } else { - this._mapLayer = new OlLayerTile({ - source: this.source, - opacity: this.layer.symbology.opacity, - }); - } - } - - private addStateListenersToOlSource() { - // TILE LOADING STATE - let tilesPending = 0; - - this.source.on('tileloadstart', () => { - tilesPending++; - this.projectService.changeRasterLayerDataStatus(this.layer, LoadingState.LOADING); - }); - this.source.on('tileloadend', () => { - tilesPending--; - if (tilesPending <= 0) { - this.projectService.changeRasterLayerDataStatus(this.layer, LoadingState.OK); - } - }); - this.source.on('tileloaderror', () => { - tilesPending--; - this.projectService.changeRasterLayerDataStatus(this.layer, LoadingState.ERROR); - }); - } - - getExtent() { - return this._mapLayer.getExtent(); - } -} diff --git a/projects/wave-core/src/lib/map/map.service.ts b/projects/wave-core/src/lib/map/map.service.ts deleted file mode 100644 index 40806fba..00000000 --- a/projects/wave-core/src/lib/map/map.service.ts +++ /dev/null @@ -1,153 +0,0 @@ -import {distinctUntilChanged} from 'rxjs/operators'; -import {BehaviorSubject, Observable} from 'rxjs'; - -import {Injectable} from '@angular/core'; -import {Extent as OlExtent} from 'ol'; -import {containsExtent as olExtentContainsExtent, getIntersection as olExtentGetIntersection} from 'ol/extent'; -import {GeometryType as OlGeometryType} from 'ol/geom'; -import {Vector as OlSourceVector} from 'ol/source'; - -import {MapContainerComponent} from './map-container/map-container.component'; - -/** - * The viewport combines… - * * the extent in map units, - * * the resolution in pixels per map unit and - * * the (optional) maximum allowed extent - */ -export interface ViewportSize { - extent: Extent; - resolution: number; - maxExtent?: [number, number, number, number]; -} - -/** - * The extent is defined as [min x, min y, max x, max y] map units - */ -export type Extent = [number, number, number, number] | OlExtent; - -/** - * The map service provides means to work with a registered map component. - */ -@Injectable() -export class MapService { - private viewportSize$ = new BehaviorSubject({ - extent: [0, 0, 0, 0], - resolution: 1, - }); - - private mapComponent: MapContainerComponent; - private isGridStream = new BehaviorSubject(false); - - constructor() {} - - /** - * Returns events that indicate if the map is in grid or default mode - */ - public get isGrid$(): Observable { - return this.isGridStream; - } - - /** - * Define if the map is in grid mode (one layer per tile) or if it displays - * all layers on one tile. - */ - public setGrid(isGrid: boolean) { - this.isGridStream.next(isGrid); - } - - /** - * This service only works if a map component is registered here upfront. - */ - public registerMapComponent(mapComponent: MapContainerComponent) { - this.mapComponent = mapComponent; - } - - public startDrawInteraction(drawType: OlGeometryType) { - if (!this.mapComponent) { - throw new Error('no MapComponent registered'); - } - this.mapComponent.startDrawInteraction(drawType); - } - - /** - * Returns whether the map currently has a draw interaction - */ - // TODO: decide to use or loose it - public isDrawInteractionAttached(): boolean { - return this.mapComponent.isDrawInteractionAttached(); - } - - /** - * Stops a draw interaction on the map and returns the output vector as result - */ - public endDrawInteraction(): OlSourceVector { - if (!this.mapComponent) { - throw new Error('no MapComponent registered'); - } - return this.mapComponent.endDrawInteraction(); - } - - /** - * Changes the viewport of the map - */ - setViewportSize(newViewportSize: ViewportSize) { - if (newViewportSize.extent.length !== 4 || newViewportSize.resolution <= 0) { - throw Error('Corrupt Viewport Size'); - } - - const oldViewportSize = this.viewportSize$.value; - - if (resolutionChanged(oldViewportSize, newViewportSize) || !extentContains(oldViewportSize, newViewportSize)) { - // TODO: buffer extent to query more data - // ol.extent.buffer(newViewportSize.extent, Math.max(w, h) * 0.5); - let newExtent = newViewportSize.extent; - - if (newViewportSize.maxExtent) { - newExtent = olExtentGetIntersection(newExtent, newViewportSize.maxExtent); - } - - newViewportSize.extent = newExtent; - - this.viewportSize$.next(newViewportSize); - } - } - - /** - * Returns the current viewport of the map - */ - getViewportSize(): ViewportSize { - return this.viewportSize$.value; - } - - /** - * Returns events that indicate the viewport upon changes of the map - * Initially emits the current viewport - */ - getViewportSizeStream(): Observable { - return this.viewportSize$.pipe(distinctUntilChanged()); - } - - /** - * Trigger a zoom event at the map to an extent - */ - zoomTo(boundingBox: Extent) { - this.mapComponent.zoomTo(boundingBox); - } -} - -/** - * Is the extent of `vps1` contained in the extent of `vps2`? - */ -function extentContains(vps1: ViewportSize, vps2: ViewportSize): boolean { - const e1 = vps1.maxExtent ? olExtentGetIntersection(vps1.extent, vps1.maxExtent) : vps1.extent; - const e2 = vps2.maxExtent ? olExtentGetIntersection(vps2.extent, vps2.maxExtent) : vps2.extent; - return olExtentContainsExtent(e1, e2); -} - -/** - * Checks for equality of the resolution component of two `ViewportSize`s - */ -function resolutionChanged(vps1: ViewportSize, vps2: ViewportSize): boolean { - return vps1.resolution !== vps2.resolution; -} diff --git a/projects/wave-core/src/lib/map/style-creator.ts b/projects/wave-core/src/lib/map/style-creator.ts deleted file mode 100644 index b3c6d485..00000000 --- a/projects/wave-core/src/lib/map/style-creator.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { - Circle as OlStyleCircle, - Fill as OlStyleFill, - Stroke as OlStyleStroke, - Style as OlStyle, - StyleFunction as OlStyleFunction, - Text as OlStyleText, -} from 'ol/style'; - -import {Feature as OlFeature} from 'ol'; - -import { - AbstractVectorSymbology, - DEFAULT_VECTOR_HIGHLIGHT_FILL_COLOR, - DEFAULT_VECTOR_HIGHLIGHT_STROKE_COLOR, - MAX_ALLOWED_POINT_RADIUS, - MAX_ALLOWED_TEXT_LENGTH, - MIN_ALLOWED_POINT_RADIUS, - PointSymbology, - SymbologyType, - VectorSymbology, -} from '../layers/symbology/symbology.model'; - -/** - * The StyleCreator genreates OpenLayers styles from a layers Symbology. - */ -export class StyleCreator { - /** - * Generate a style from a vector layer symbology. - */ - public static fromVectorSymbology(sym: AbstractVectorSymbology): OlStyleFunction | OlStyle { - switch (sym.getSymbologyType()) { - case SymbologyType.SIMPLE_POINT: - case SymbologyType.CLUSTERED_POINT: - case SymbologyType.COMPLEX_POINT: - return StyleCreator.fromComplexPointSymbology(sym as PointSymbology); - - case SymbologyType.SIMPLE_LINE: - case SymbologyType.COMPLEX_LINE: - return StyleCreator.fromComplexVectorSymbology(sym as VectorSymbology); - - case SymbologyType.SIMPLE_VECTOR: - case SymbologyType.COMPLEX_VECTOR: - return StyleCreator.fromComplexVectorSymbology(sym as VectorSymbology); - - default: - console.error('StyleCreator: unknown AbstractSymbology: ' + sym.getSymbologyType()); - return StyleCreator.fromComplexVectorSymbology(sym as VectorSymbology); // VectorSymbology should handle all types - } - } - - /** - * Handles radius attribute values and converts them to valid radius. - */ - static handleRadiusAttributeValue(radius: number | string, radiusScale: number = 1.0): number | undefined { - const numberRadius = typeof radius === 'string' ? parseFloat(radius) : radius; - if (radius === undefined || radius === null) { - return undefined; - } - if (numberRadius > MAX_ALLOWED_POINT_RADIUS) { - return MAX_ALLOWED_POINT_RADIUS; - } else if (numberRadius < MIN_ALLOWED_POINT_RADIUS) { - return MIN_ALLOWED_POINT_RADIUS; - } else { - return Math.trunc(numberRadius * radiusScale); - } - } - - /** - * Handles text attribute values and converts them to a string or number for display. - */ - static handleTextAttributeValue(text: string | number): string | number | undefined { - if (text === undefined || text === null) { - return undefined; - } - if (typeof text === 'string') { - return text.slice(0, MAX_ALLOWED_TEXT_LENGTH); - } - return text; - } - - /** - * Warps a Symbology into a highlighted Symbology. - */ - static createHighlightSymbology(sym: S): S { - const highlightSymbology: S = sym.clone() as S; - highlightSymbology.fillRGBA = DEFAULT_VECTOR_HIGHLIGHT_FILL_COLOR; - highlightSymbology.strokeRGBA = DEFAULT_VECTOR_HIGHLIGHT_STROKE_COLOR; - return highlightSymbology; - } - - /** - * Generate a style key (string) for a feature. - */ - static buildStyleKey( - featureFillColorValue: string | number | undefined, - featureStrokeColorValue: string | number | undefined, - featureTextValue: string | number | undefined, - featureRadiusValue: string | number | undefined, - ): string { - const VALUE_SEPARATOR_SYMBOL = ':::'; - return ( - `${featureFillColorValue}${VALUE_SEPARATOR_SYMBOL}${featureStrokeColorValue}${VALUE_SEPARATOR_SYMBOL}` + - `${featureTextValue}${VALUE_SEPARATOR_SYMBOL}${featureRadiusValue}` - ); - } - - /** - * Generate an OpenLayers style function for vector layers. - */ - static fromComplexVectorSymbology(sym: VectorSymbology): OlStyleFunction { - // we need a style cache to speed things up. This dangles in the void of the GC... - const styleCache: {[key: string]: OlStyle} = {}; - - return (feature: OlFeature, resolution: number) => { - const featureFillColorValue = - sym.fillColorAttribute && sym.describesElementFill() ? feature.get(sym.fillColorAttribute) : undefined; - const featureStrokeColorValue = sym.strokeColorAttribute ? feature.get(sym.strokeColorAttribute) : undefined; - const featureTextValue = sym.textAttribute ? StyleCreator.handleTextAttributeValue(feature.get(sym.textAttribute)) : undefined; - const styleKey = StyleCreator.buildStyleKey(featureFillColorValue, featureStrokeColorValue, featureTextValue, undefined); - - if (!styleCache[styleKey]) { - const fillColorBreakpointLookup = sym.fillColorizer.getBreakpointForValue(featureFillColorValue, true); - const fillColor = fillColorBreakpointLookup ? fillColorBreakpointLookup.rgba.rgbaTuple() : sym.fillRGBA.rgbaTuple(); - - const strokeColorBreakpointLookup = sym.strokeColorizer.getBreakpointForValue(featureStrokeColorValue, true); - const strokeColor = strokeColorBreakpointLookup ? strokeColorBreakpointLookup.rgba.rgbaTuple() : sym.strokeRGBA.rgbaTuple(); - - const fillStyle = new OlStyleFill({color: fillColor}); - const strokeStyle = new OlStyleStroke({color: strokeColor, width: sym.strokeWidth}); - - if (sym.strokeDashStyle && sym.strokeDashStyle.length > 1) { - strokeStyle.setLineDash(sym.strokeDashStyle); - } - - // only build the text style if we are going to show it - const textStyle = !featureTextValue - ? undefined - : new OlStyleText({ - text: featureTextValue.toString(), - fill: new OlStyleFill({ - color: sym.textColor.rgbaTuple(), - }), - stroke: new OlStyleStroke({ - color: sym.strokeRGBA.rgbaTuple(), - width: sym.textStrokeWidth, - }), - overflow: true, - }); - - const style = new OlStyle({ - stroke: strokeStyle, - fill: fillStyle, - text: textStyle, - }); - styleCache[styleKey] = style; - } - - return styleCache[styleKey]; - }; - } - - /** - * Generate an OpenLayers style function for point layers. - */ - static fromComplexPointSymbology(sym: PointSymbology): OlStyleFunction { - // we need a style cache to speed things up. This dangles in the void of the GC... - const styleCache: {[key: string]: OlStyle} = {}; - - return (feature: OlFeature, resolution: number) => { - const featureFillColorValue = - sym.fillColorAttribute && sym.describesElementFill() ? feature.get(sym.fillColorAttribute) : undefined; - const featureStrokeColorValue = sym.strokeColorAttribute ? feature.get(sym.strokeColorAttribute) : undefined; - const featureTextValue = sym.textAttribute ? StyleCreator.handleTextAttributeValue(feature.get(sym.textAttribute)) : undefined; - const featureRadiusValue = sym.radiusAttribute - ? StyleCreator.handleRadiusAttributeValue(feature.get(sym.radiusAttribute)) - : undefined; - - const styleKey = StyleCreator.buildStyleKey( - featureFillColorValue, - featureStrokeColorValue, - featureTextValue, - featureRadiusValue, - ); - - if (!styleCache[styleKey]) { - const fillColorBreakpointLookup = sym.fillColorizer.getBreakpointForValue(featureFillColorValue, true); - const fillColor = fillColorBreakpointLookup ? fillColorBreakpointLookup.rgba.rgbaTuple() : sym.fillRGBA.rgbaTuple(); - - const strokeColorBreakpointLookup = sym.strokeColorizer.getBreakpointForValue(featureStrokeColorValue, true); - const strokeColor = strokeColorBreakpointLookup ? strokeColorBreakpointLookup.rgba.rgbaTuple() : sym.strokeRGBA.rgbaTuple(); - - const fillStyle = new OlStyleFill({color: fillColor}); - const strokeStyle = new OlStyleStroke({color: strokeColor, width: sym.strokeWidth}); - - if (sym.strokeDashStyle && sym.strokeDashStyle.length > 1) { - strokeStyle.setLineDash(sym.strokeDashStyle); - } - - const radius = featureRadiusValue ? featureRadiusValue : sym.radius; - - const imageStyle = new OlStyleCircle({ - radius, - fill: fillStyle, - stroke: strokeStyle, - }); - - // only build the text style if we are going to show it - const textStyle = !featureTextValue - ? undefined - : new OlStyleText({ - text: featureTextValue.toString(), - fill: new OlStyleFill({ - color: sym.textColor.rgbaTuple(), - }), - stroke: new OlStyleStroke({ - color: sym.strokeRGBA.rgbaTuple(), - width: sym.textStrokeWidth, - }), - }); - - const style = new OlStyle({ - image: imageStyle, - text: textStyle, - }); - styleCache[styleKey] = style; - } - - return styleCache[styleKey]; - }; - } -} diff --git a/projects/wave-core/src/lib/map/zoom-handles/zoom-handles.component.html b/projects/wave-core/src/lib/map/zoom-handles/zoom-handles.component.html deleted file mode 100644 index ad5fa13d..00000000 --- a/projects/wave-core/src/lib/map/zoom-handles/zoom-handles.component.html +++ /dev/null @@ -1,8 +0,0 @@ -
    - - -
    diff --git a/projects/wave-core/src/lib/map/zoom-handles/zoom-handles.component.scss b/projects/wave-core/src/lib/map/zoom-handles/zoom-handles.component.scss deleted file mode 100644 index 6cb8a667..00000000 --- a/projects/wave-core/src/lib/map/zoom-handles/zoom-handles.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.container { - padding: 2px 2px; -} diff --git a/projects/wave-core/src/lib/map/zoom-handles/zoom-handles.component.ts b/projects/wave-core/src/lib/map/zoom-handles/zoom-handles.component.ts deleted file mode 100644 index 2279f2fe..00000000 --- a/projects/wave-core/src/lib/map/zoom-handles/zoom-handles.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {ChangeDetectionStrategy, Component, EventEmitter, OnInit, Output} from '@angular/core'; - -@Component({ - selector: 'wave-zoom-handles', - templateUrl: './zoom-handles.component.html', - styleUrls: ['./zoom-handles.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ZoomHandlesComponent implements OnInit { - @Output() zoomIn = new EventEmitter(); - - @Output() zoomOut = new EventEmitter(); - - constructor() {} - - ngOnInit() {} -} diff --git a/projects/wave-core/src/lib/notification.service.ts b/projects/wave-core/src/lib/notification.service.ts deleted file mode 100644 index 829ca150..00000000 --- a/projects/wave-core/src/lib/notification.service.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {Injectable} from '@angular/core'; -import {Subject, Observable} from 'rxjs'; -import {MatSnackBar} from '@angular/material/snack-bar'; - -export enum NotificationType { - Info, - Error, -} - -interface Notification { - type: NotificationType; - message: string; -} - -@Injectable() -export class NotificationService { - private notification$ = new Subject(); - - constructor(private snackBar: MatSnackBar) {} - - getNotificationStream(): Observable { - return this.notification$; - } - - info(message: string) { - this.notification$.next({ - type: NotificationType.Info, - message: message, - }); - this.snackBar.open(message, undefined, { - duration: 3000, - }); - } - - error(message: string) { - this.notification$.next({ - type: NotificationType.Error, - message: message, - }); - this.snackBar.open(message, undefined, { - duration: 5000, - }); - } -} diff --git a/projects/wave-core/src/lib/operators/datatype.model.ts b/projects/wave-core/src/lib/operators/datatype.model.ts deleted file mode 100644 index 1e1bc554..00000000 --- a/projects/wave-core/src/lib/operators/datatype.model.ts +++ /dev/null @@ -1,217 +0,0 @@ -/** - * A class about a data type. - */ -export abstract class DataType { - /** - * Create a human readable output of the data type. - * @returns The name. - */ - abstract toString(): string; - - /** - * @return The name of the projection. - */ - abstract getCode(): string; - - /** - * @return the largest value. - */ - abstract getMin(): number; - - /** - * @return the smallest value. - */ - abstract getMax(): number; -} - -class Byte extends DataType { - toString(): string { - return 'Byte'; - } - - getCode(): string { - return 'Byte'; - } - - getMin(): number { - return 0; - } - - getMax(): number { - return 255; - } -} - -class Int16 extends DataType { - toString(): string { - return 'Int 16'; - } - - getCode(): string { - return 'Int16'; - } - - getMin(): number { - return -32768; - } - - getMax(): number { - return 32767; - } -} - -class UInt16 extends DataType { - toString(): string { - return 'Unsigned Int 16'; - } - - getCode(): string { - return 'UInt16'; - } - - getMin(): number { - return 0; - } - - getMax(): number { - return 65535; - } -} - -class Int32 extends DataType { - toString(): string { - return 'Int 32'; - } - - getCode(): string { - return 'Int32'; - } - - getMin(): number { - return -2147483648; - } - - getMax(): number { - return 2147483647; - } -} - -class UInt32 extends DataType { - toString(): string { - return 'Unsigned Int 32'; - } - - getCode(): string { - return 'UInt32'; - } - - getMin(): number { - return 0; - } - - getMax(): number { - return 4294967295; - } -} - -class Float32 extends DataType { - toString(): string { - return 'Float 32'; - } - - getCode(): string { - return 'Float32'; - } - - getMin(): number { - return Number.POSITIVE_INFINITY; - } - - getMax(): number { - return Number.NEGATIVE_INFINITY; - } -} - -class Float64 extends DataType { - toString(): string { - return 'Float 64'; - } - - getCode(): string { - return 'Float64'; - } - - getMin(): number { - return Number.POSITIVE_INFINITY; - } - - getMax(): number { - return Number.NEGATIVE_INFINITY; - } -} - -class Alphanumeric extends DataType { - toString(): string { - return 'String'; - } - - getCode(): string { - return 'Alphanumeric'; - } - - getMin(): number { - return undefined; - } - - getMax(): number { - return undefined; - } -} - -export class DataTypeCollection { - static readonly INSTANCE = new DataTypeCollection(); - - /* eslint-disable @typescript-eslint/naming-convention,no-underscore-dangle,id-blacklist,id-match */ - Byte: DataType = new Byte(); - Int16: DataType = new Int16(); - UInt16: DataType = new UInt16(); - Int32: DataType = new Int32(); - UInt32: DataType = new UInt32(); - Float32: DataType = new Float32(); - Float64: DataType = new Float64(); - Alphanumeric: DataType = new Alphanumeric(); - /* eslint-enable */ - - ALL_DATATYPES: Array; - ALL_NUMERICS: Array; - - protected constructor() { - this.ALL_DATATYPES = [this.Byte, this.Int16, this.UInt16, this.Int32, this.UInt32, this.Float32, this.Float64, this.Alphanumeric]; - this.ALL_NUMERICS = [this.Byte, this.Int16, this.UInt16, this.Int32, this.UInt32, this.Float32, this.Float64]; - } - - fromCode(code: string) { - switch (code) { - case this.Byte.getCode(): - return this.Byte; - case this.Int16.getCode(): - return this.Int16; - case this.UInt16.getCode(): - return this.UInt16; - case this.Int32.getCode(): - return this.Int32; - case this.UInt32.getCode(): - return this.UInt32; - case this.Float32.getCode(): - return this.Float32; - case this.Float64.getCode(): - return this.Float64; - case this.Alphanumeric.getCode(): - return this.Alphanumeric; - default: - throw new Error(`Invalid Data Type: ${code}`); - } - } -} - -export const DataTypes = DataTypeCollection.INSTANCE; // eslint-disable-line @typescript-eslint/naming-convention, no-underscore-dangle, id-blacklist, id-match diff --git a/projects/wave-core/src/lib/operators/dialogs/baskets/gfbio-basket-result.component.ts b/projects/wave-core/src/lib/operators/dialogs/baskets/gfbio-basket-result.component.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/operators/dialogs/box-plot-operator/box-plot-operator.component.html b/projects/wave-core/src/lib/operators/dialogs/box-plot-operator/box-plot-operator.component.html deleted file mode 100644 index 1a572d11..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/box-plot-operator/box-plot-operator.component.html +++ /dev/null @@ -1,91 +0,0 @@ -Box plot -
    -
    - - - There must be at least one numerical attribute in this layer. - - -
    -
    -
    - -
    - - -
    -
    -
    - - - {{ attribute }} - - - -
    -
    -
    - - - Notch -
    - Mean value -
    - - - - - - - The name must be non-empty. - - -
    -
    -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/box-plot-operator/box-plot-operator.component.scss b/projects/wave-core/src/lib/operators/dialogs/box-plot-operator/box-plot-operator.component.scss deleted file mode 100644 index a0f82faf..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/box-plot-operator/box-plot-operator.component.scss +++ /dev/null @@ -1,13 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} -.actions { - text-align: right; - padding: 1rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/box-plot-operator/box-plot-operator.component.ts b/projects/wave-core/src/lib/operators/dialogs/box-plot-operator/box-plot-operator.component.ts deleted file mode 100644 index 748f807e..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/box-plot-operator/box-plot-operator.component.ts +++ /dev/null @@ -1,125 +0,0 @@ -import {AfterViewInit, ChangeDetectionStrategy, Component, OnInit, OnDestroy} from '@angular/core'; -import {AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators} from '@angular/forms'; -import {ResultTypes} from '../../result-type.model'; -import {AbstractSymbology} from '../../../layers/symbology/symbology.model'; -import {Layer} from '../../../layers/layer.model'; -import {Operator} from '../../operator.model'; -import {Plot} from '../../../plots/plot.model'; -import {ProjectService} from '../../../project/project.service'; -import {WaveValidators} from '../../../util/form.validators'; -import {BoxPlotType} from '../../types/boxplot-type.model'; -import {BehaviorSubject, Subscription} from 'rxjs'; -import {DataTypes} from '../../datatype.model'; - -@Component({ - selector: 'wave-box-plot-operator', - templateUrl: './box-plot-operator.component.html', - styleUrls: ['./box-plot-operator.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class BoxPlotComponent implements OnInit, AfterViewInit, OnDestroy { - readonly ResultTypes = ResultTypes; - - form: FormGroup; - layers: Array>; - selectedLayers = new BehaviorSubject>([]); - hasNumerics = new BehaviorSubject(false); - max = 5; - - private subscriptions: Array = []; - - constructor(private formBuilder: FormBuilder, private projectService: ProjectService) {} - - ngOnInit() { - this.form = this.formBuilder.group({ - vLayer: [undefined, Validators.required], - notch: [false, Validators.required], - mean: [false, Validators.required], - range: [1.5, [Validators.required, this.nonNegative]], - name: ['', [Validators.required, WaveValidators.notOnlyWhitespace]], - }); - this.subscriptions.push( - this.form.controls['vLayer'].valueChanges.subscribe((change) => { - this.selectedLayers.next([]); - const inputOperator = change.operator as Operator; - this.hasNumerics.next(inputOperator.dataTypes.some((dataType) => DataTypes.ALL_NUMERICS.includes(dataType))); - }), - ); - } - - increase() { - const inputOperator = this.form.controls['vLayer'].value.operator as Operator; - - const [numericAttribute] = inputOperator.dataTypes.findEntry((value) => { - return DataTypes.ALL_NUMERICS.indexOf(value) >= 0; - }); - - if (numericAttribute) { - const newSelectedLayers = [...this.selectedLayers.getValue()]; - newSelectedLayers[this.selectedLayers.getValue().length] = {attr: numericAttribute}; - this.selectedLayers.next(newSelectedLayers); - } else { - this.form.controls['vLayer'].setErrors({noNumericalAttributes: true}); - } - } - - decrease() { - this.selectedLayers.next(this.selectedLayers.getValue().slice(0, this.selectedLayers.getValue().length - 1)); - } - - add() { - const sourceOperator = this.form.controls['vLayer'].value.operator; - const selectedLayers = new Array(); - for (const item of this.selectedLayers.getValue()) { - selectedLayers.push(item.attr); - } - const operator: Operator = new Operator({ - operatorType: new BoxPlotType({ - notch: this.form.controls['notch'].value, - mean: this.form.controls['mean'].value, - range: this.form.controls['range'].value, - attributes: selectedLayers, - inputType: sourceOperator.resultType, - }), - resultType: ResultTypes.PLOT, - projection: sourceOperator.projection, - pointSources: sourceOperator.resultType === ResultTypes.POINTS ? [sourceOperator] : undefined, - lineSources: sourceOperator.resultType === ResultTypes.LINES ? [sourceOperator] : undefined, - polygonSources: sourceOperator.resultType === ResultTypes.POLYGONS ? [sourceOperator] : undefined, - }); - const plot = new Plot({ - name: this.form.controls['name'].value, - operator, - }); - this.projectService.addPlot(plot); - } - - ngAfterViewInit() { - setTimeout(() => { - this.form.updateValueAndValidity({ - onlySelf: false, - emitEvent: true, - }); - this.form.controls['vLayer'].updateValueAndValidity(); - - const nameSuggestion = ' of ' + (this.form.controls['vLayer'].value ? this.form.controls['vLayer'].value.name : ''); - this.form.controls['name'].setValue('Box plot' + nameSuggestion); - }); - } - - updateAttribute(i: number, attribute: string) { - const newSelectedLayers = [...this.selectedLayers.getValue()]; - newSelectedLayers[i] = {attr: attribute}; - this.selectedLayers.next(newSelectedLayers); - } - - nonNegative(val: number): ValidatorFn { - return (control: AbstractControl): {[key: string]: any} => { - return val < 0 ? {negativeNumber: {value: control.value}} : null; - }; - } - - ngOnDestroy() { - this.subscriptions.forEach((sub) => sub.unsubscribe()); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/country-polygon-selection/country-polygon-selection.component.html b/projects/wave-core/src/lib/operators/dialogs/country-polygon-selection/country-polygon-selection.component.html deleted file mode 100644 index fd3cd552..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/country-polygon-selection/country-polygon-selection.component.html +++ /dev/null @@ -1,31 +0,0 @@ -Country Selection - - - - - - - Country Name - - - - - - Area - {{ entry[sourceAreaColumn] * 10 }} km² - - - - - - - -
    - -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/country-polygon-selection/country-polygon-selection.component.scss b/projects/wave-core/src/lib/operators/dialogs/country-polygon-selection/country-polygon-selection.component.scss deleted file mode 100644 index 6f615ced..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/country-polygon-selection/country-polygon-selection.component.scss +++ /dev/null @@ -1,25 +0,0 @@ -mat-toolbar ::ng-deep mat-toolbar-row:first-child { - display: none; -} - -p { - color: var(--wave-foreground-secondary-text-color, black); -} - -mat-row { - cursor: pointer; -} - -mat-row:hover { - background-color: var(--wave-background-hover-color, grey); -} - -mat-cell ::ng-deep .highlight { - color: var(--wave-accent-color, grey); -} - -mat-progress-spinner { - width: 25%; - height: auto; - margin: 2rem auto; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/country-polygon-selection/country-polygon-selection.component.ts b/projects/wave-core/src/lib/operators/dialogs/country-polygon-selection/country-polygon-selection.component.ts deleted file mode 100644 index 20026be3..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/country-polygon-selection/country-polygon-selection.component.ts +++ /dev/null @@ -1,228 +0,0 @@ -import {combineLatest as observableCombineLatest, ReplaySubject, Subscription, BehaviorSubject, Observable} from 'rxjs'; -import {tap, mergeMap, map} from 'rxjs/operators'; - -import {ChangeDetectionStrategy, Component, OnDestroy, OnInit} from '@angular/core'; -import {UserService} from '../../../users/user.service'; -import {Operator} from '../../operator.model'; -import {VectorData, VectorLayer} from '../../../layers/layer.model'; -import {ResultTypes} from '../../result-type.model'; -import {VectorSymbology} from '../../../layers/symbology/symbology.model'; -import {RandomColorService} from '../../../util/services/random-color.service'; -import {MatDialog} from '@angular/material/dialog'; -import {ProjectService} from '../../../project/project.service'; -import {Projection, Projections} from '../../projection.model'; -import {CSVParameters, CsvSourceType} from '../../types/csv-source-type.model'; -import {MappingQueryService} from '../../../queries/mapping-query.service'; -import {WFSOutputFormats} from '../../../queries/output-formats/wfs-output-format.model'; -import {TextualAttributeFilterEngineType, TextualAttributeFilterType} from '../../types/textual-attribute-filter-type.model'; -import {DataSource} from '@angular/cdk/table'; -import {DataType, DataTypes} from '../../datatype.model'; - -function nameComparator(a: string, b: string): number { - const stripped = (s: string): string => s.replace(' ', ''); - return stripped(a).localeCompare(stripped(b)); -} - -@Component({ - selector: 'wave-country-polygon-selection', - templateUrl: './country-polygon-selection.component.html', - styleUrls: ['./country-polygon-selection.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class CountryPolygonSelectionComponent implements OnInit, OnDestroy { - searchString$ = new BehaviorSubject(''); - filteredEntries$ = new ReplaySubject>(1); - - tableEntries: CountryDataSource; - displayedColumns: Array = ['name', 'area']; - - sourceIdColumn = 'NAME'; - sourceAreaColumn = 'AREA'; - - isLoading$ = new BehaviorSubject(true); - - /* - { - "filename": "file:///home/gfbio/data/dev/csv_source/country_borders.csv", - "on_error": "keep", - "separator": ",", - "geometry": "wkt", - "time": "none", - "columns": { - "x": "WKT", - "textual": ["FIPS", "ISO2", "ISO3", "UN", "NAME"], - "numeric": ["AREA", "POP2005", "REGION", "SUBREGION", "LON", "LAT"] - } - } - */ - - private sourceFile = 'file:///home/gfbio/data/dev/csv_source/country_borders.csv'; - private sourceParameters: CSVParameters = { - header: 0, - onError: 'keep', - fieldSeparator: ',', - geometry: 'wkt', - time: 'none', - columns: { - x: 'WKT', - textual: ['FIPS', 'ISO2', 'ISO3', 'UN', 'NAME'], - numeric: ['AREA', 'POP2005', 'REGION', 'SUBREGION', 'LON', 'LAT'], - }, - provenance: { - citation: `TM_WORLD_BORDERS-0.1.ZIP - -Provided by Bjorn Sandvik, thematicmapping.org - -Use this dataset with care, as several of the borders are disputed. - -The original shapefile (world_borders.zip, 3.2 MB) was downloaded from the Mapping Hacks website: -http://www.mappinghacks.com/data/ - -The dataset was derived by Schuyler Erle from public domain sources. -Sean Gilles did some clean up and made some enhancements.`, - uri: '', - license: 'Creative Commons Attribution-Share Alike License 3.0', - }, - }; - private sourceProjection: Projection = Projections.WGS_84; - private sourceOperator: Operator; - private subscription: Subscription; - - constructor( - private userService: UserService, - private projectService: ProjectService, - private randomColorService: RandomColorService, - private mappingQueryService: MappingQueryService, - public dialog: MatDialog, - ) {} - - ngOnInit() { - this.sourceOperator = this.createCsvSourceOperator(); - - this.subscription = observableCombineLatest( - this.getOperatorDataStream().pipe( - map((vectorData) => { - // console.log('vectorData', vectorData); - const data = vectorData.data.map((olFeature) => olFeature.getProperties() as {[k: string]: any}); - // console.log('mapped', data); - return data; - }), - ), - this.searchString$.pipe(map((searchString) => searchString.toLowerCase())), - (entries, searchString) => - entries - .filter((entry) => entry[this.sourceIdColumn].toString().toLowerCase().indexOf(searchString) >= 0) - .sort((a, b) => nameComparator(a[this.sourceIdColumn].toString(), b[this.sourceIdColumn].toString())), - ) - .pipe(tap(() => this.isLoading$.next(false))) - .subscribe((entries) => this.filteredEntries$.next(entries)); - - this.tableEntries = new CountryDataSource(this.filteredEntries$); - } - - ngOnDestroy() { - this.subscription.unsubscribe(); - } - - createCsvSourceOperator(): Operator { - const csvSourceType = new CsvSourceType({ - dataURI: this.sourceFile, - parameters: this.sourceParameters, - }); - - const dataTypes = new Map(); - const attributes = new Array(); - - for (const an of this.sourceParameters.columns.numeric) { - attributes.push(an); - dataTypes.set(an, DataTypes.Float64); // TODO: get more accurate type - } - - for (const an of this.sourceParameters.columns.textual) { - attributes.push(an); - dataTypes.set(an, DataTypes.Alphanumeric); // TODO: get more accurate type - } - - const op = new Operator({ - operatorType: csvSourceType, - resultType: ResultTypes.POLYGONS, - projection: this.sourceProjection, - attributes, - dataTypes, - }); - - return op; - } - - getOperatorDataStream(): Observable { - return this.projectService.getTimeStream().pipe( - mergeMap((t) => { - return this.mappingQueryService - .getWFSData({ - operator: this.sourceOperator, - projection: this.sourceProjection, - clusteredOption: undefined, - outputFormat: WFSOutputFormats.JSON, - viewportSize: { - extent: this.sourceProjection.getExtent(), - resolution: 1, - }, - time: t, - }) - .pipe(map((d) => VectorData.olParse(t, this.sourceProjection, this.sourceProjection.getExtent(), d))); - }), - ); - } - - createFilterOperator(key: string): Operator { - const filterOperatorType = new TextualAttributeFilterType({ - attributeName: this.sourceIdColumn, - engine: TextualAttributeFilterEngineType.EXACT, - searchString: key, - }); - - const sourceOp = this.createCsvSourceOperator(); - - return new Operator({ - operatorType: filterOperatorType, - resultType: this.sourceOperator.resultType, - projection: this.sourceOperator.projection, - polygonSources: [sourceOp], - attributes: sourceOp.attributes, - dataTypes: sourceOp.dataTypes, - }); - } - - addLayer(layerName: string, operator: Operator) { - const symbology = VectorSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - - const layer = new VectorLayer({ - name: layerName, - operator, - symbology, - }); - - this.projectService.addLayer(layer); - } -} - -interface CountryMapType { - [key: string]: string | number; -} - -class CountryDataSource extends DataSource { - private countries: Observable>; - - constructor(countries: Observable>) { - super(); - this.countries = countries; - } - - connect(): Observable> { - return this.countries; - } - - disconnect() {} -} diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-properties/csv-properties-template.component.html b/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-properties/csv-properties-template.component.html deleted file mode 100644 index 3e8324cf..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-properties/csv-properties-template.component.html +++ /dev/null @@ -1,360 +0,0 @@ - - - - Data - -
    - - - - - - - - - -
    - - - - {{ delimiter.def }} - - - -
    - - - - - - {{ textQualifier }} - - - -
    - - - - - - - - - -
    - - - - {{ decimalSeparator }} - - - -
    - - - - - -
    -
    -
    - - Spatial - -
    -
    -
    - - - - - - {{ h.value }} - - - {{ 'unnamed' }} - - - - - -
    -
    - - - - {{ projection }} - - - -
    -
    -
    -
    - - - - - - {{ h.value }} - - - {{ 'unnamed' }} - - - - - -
    -
    - - - - {{ c }} - - - -
    -
    -
    - WKT - - - - {{ rt.toString() }} - - - -
    -
    -
    - - -
    Temporal
    -
    - -
    - The file includes temporal data. - - - - {{ intervalType.display }} - - - -
    -
    - - - - - - {{ h.value }} - - - {{ 'unnamed' }} - - - - - -
    -
    - - - - - - {{ h.value }} - - - {{ 'unnamed' }} - - - - - - - - {{ temporalProperties.controls['endFormat'].value }} - -
    -
    -
    -
    - - - - {{ timeFormat.display }} - - - -
    -
    - - - - - {{ timeFormat.display }} - - - - - {{ durationFormat.display }} - - - - -
    -
    -
    -
    - - Typing - - - - Layer - -
    - - - Name is already in use. - - - - - Skip - - - Abort - - - Keep - - -
    -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-properties/csv-properties.component.scss b/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-properties/csv-properties.component.scss deleted file mode 100644 index 43950889..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-properties/csv-properties.component.scss +++ /dev/null @@ -1,35 +0,0 @@ -$latitudeColor: #26c5ff; -$longitudeColor: orange; -$startColor: darkgreen; -$endColor: darkviolet; -$backgroundColor: var(--wave-primary-color, grey); -$titleColor: white; /*Inherit from theme here.*/ - -div.latitudeSelector mat-select ::ng-deep span.mat-select-placeholder { - color: $latitudeColor; -} - -div.longitudeSelector mat-select ::ng-deep span.mat-select-placeholder { - color: $longitudeColor; -} - -div.startSelector mat-select ::ng-deep span.mat-select-placeholder { - color: $startColor; -} - -div.endSelector mat-select ::ng-deep span.mat-select-placeholder { - color: $endColor; -} - -div.constantSelector mat-form-field ::ng-deep span.mat-input-placeholder { - color: $endColor; -} - -.custom mat-form-field ::ng-deep label.mat-input-placeholder { - color: $titleColor; - opacity: 0.75; -} - -.error { - color: var(--wave-warn-color, red); -} diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-properties/csv-properties.component.ts b/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-properties/csv-properties.component.ts deleted file mode 100644 index 2b875f38..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-properties/csv-properties.component.ts +++ /dev/null @@ -1,629 +0,0 @@ -import {Observable, BehaviorSubject, Subscription, ReplaySubject} from 'rxjs'; -import {map} from 'rxjs/operators'; - -import { - Component, - ChangeDetectionStrategy, - OnInit, - AfterViewInit, - Input, - OnDestroy, - ChangeDetectorRef, - ViewChild, - ElementRef, -} from '@angular/core'; -import {FormGroup, Validators, FormControl, ValidatorFn, AbstractControl} from '@angular/forms'; -import {IntervalFormat} from '../../interval.enum'; -import {Projection, Projections} from '../../../../projection.model'; -import {UserService} from '../../../../../users/user.service'; -import {WaveValidators} from '../../../../../util/form.validators'; -import {MatStepper} from '@angular/material/stepper'; -import {CsvPropertiesService} from '../../csv-dialog/csv.properties.service'; -import {ResultType, ResultTypes} from '../../../../result-type.model'; - -export interface DataPropertiesDict { - delimiter: string; - decimalSeparator: string; - isTextQualifier: boolean; - textQualifier: string; - isHeaderRow: boolean; - headerRow: number; -} - -export interface SpatialPropertiesDict { - xColumn: number; - yColumn: number; - spatialReferenceSystem: Projection; - coordinateFormat: string; - isWkt: boolean; - wktResultType: ResultType; -} - -export interface TemporalPropertiesDict { - intervalType: IntervalFormat; - isTime: boolean; - startColumn: number; - startFormat: string; - endColumn: number; - endFormat: string; - constantDuration: number; -} - -export interface IntervalType { - display: string; - value: IntervalFormat; - requiredColumns: number; -} - -export const INTERVAL_TYPE_SELECT_ID = 'csv_interval_select', - LAYER_NAME_INPUT_ID = 'csv_layer_name_input', - IS_TIME_TOGGLE_ID = 'csv_is_time_toggle'; - -export enum FormStatus { - DataProperties, - SpatialProperties, - TemporalProperties, - TypingProperties, - LayerProperties, - Loading, -} - -@Component({ - selector: 'wave-csv-properties', - templateUrl: './csv-properties-template.component.html', - styleUrls: ['./csv-properties.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class CsvPropertiesComponent implements OnInit, AfterViewInit, OnDestroy { - Projections = Projections; - FormStatus = FormStatus; - IntervalFormat = IntervalFormat; - INTERVAL_TYPE_SELECT_ID = INTERVAL_TYPE_SELECT_ID; - LAYER_NAME_INPUT_ID = LAYER_NAME_INPUT_ID; - IS_TIME_TOGGLE_ID = IS_TIME_TOGGLE_ID; - - isSpatialVisited = false; - - delimiters: {def: string; value: string}[] = [ - {def: 'TAB', value: '\t'}, - {def: 'COMMA', value: ','}, - {def: 'SEMICOLON', value: ';'}, - ]; - - // http://man7.org/linux/man-pages/man3/strptime.3.html - timeFormats: Array<{display: string; value: string}> = [ - {display: 'yyyy-MM-ddTHH:mm:ssZ', value: '%Y-%m-%dT%H:%M:%SZ'}, - {display: 'yyyy-MM-ddTHH:mmZ', value: '%Y-%m-%dT%H:%MZ'}, - {display: 'dd-MM-yyyy HH:mm:ss', value: '%d-%m-%Y %H:%M:%S'}, - {display: 'dd.MM.yyyy HH:mm:ss', value: '%d.%m.%Y %H:%M:%S'}, - {display: 'yyyy-MM-dd HH:mm:ssZ', value: '%Y-%m-%d %H:%M:%SZ'}, - {display: 'yyyy-MM-dd HH:mmZ', value: '%Y-%m-%d %H:%MZ'}, - {display: 'dd.MM.yyyy', value: '%d.%m.%Y'}, - {display: 'yyyy-MM-dd', value: '%Y-%m-%d'}, - ]; - durationFormats: Array<{display: string; value: string}> = [ - // {display: 'days', value: 'd'}, - // {display: 'hours', value: 'h'}, - {display: 'seconds', value: 'seconds'}, - ]; - intervalTypes: IntervalType[] = [ - {display: '[Start,+inf)', value: IntervalFormat.StartInf, requiredColumns: 1}, - {display: '[Start, End]', value: IntervalFormat.StartEnd, requiredColumns: 2}, - {display: '[Start, Start+Duration]', value: IntervalFormat.StartDur, requiredColumns: 2}, - {display: '[Start, Start+Constant]', value: IntervalFormat.StartConst, requiredColumns: 1}, - ]; - decimalSeparators: string[] = [',', '.']; - textQualifiers: string[] = ['"', "'"]; - coordinateFormats: string[] = ['Degrees Minutes Seconds', 'Degrees Decimal Minutes', 'Decimal Degrees']; - vectorTypes = ResultTypes.VECTOR_TYPES; - - dataProperties: FormGroup = new FormGroup({ - delimiter: new FormControl(this.delimiters[1].value, Validators.required), - decimalSeparator: new FormControl(this.decimalSeparators[1], Validators.required), - isTextQualifier: new FormControl(true), - textQualifier: new FormControl({value: this.textQualifiers[0], disabled: true}, Validators.required), - isHeaderRow: new FormControl(true), - headerRow: new FormControl({value: 0, disabled: true}, Validators.required), - }); - spatialProperties: FormGroup = new FormGroup({ - xColumn: new FormControl(0, Validators.required), - yColumn: new FormControl(1, Validators.required), - spatialReferenceSystem: new FormControl(Projections.WGS_84), - coordinateFormat: new FormControl({value: this.coordinateFormats[2], disabled: true}, Validators.required), - isWkt: new FormControl(false, Validators.required), - wktResultType: new FormControl({value: this.vectorTypes[0], disabled: true}, Validators.required), - }); - temporalProperties: FormGroup = new FormGroup({ - intervalType: new FormControl(IntervalFormat.StartInf), - isTime: new FormControl(false), - startColumn: new FormControl(2), - startFormat: new FormControl(this.timeFormats[0].value), - endColumn: new FormControl(3), - endFormat: new FormControl(this.timeFormats[0].value), - constantDuration: new FormControl(0), - }); - typingProperties: FormGroup = new FormGroup({}); - layerProperties: FormGroup = new FormGroup({}); - - dialogTitle: string; - subtitleDescription: string; - - formStatus$: BehaviorSubject = new BehaviorSubject(this.FormStatus.Loading); - isDataProperties$: Observable; - isSpatialProperties$: Observable; - isTemporalProperties$: Observable; - isTypingProperties$: Observable; - isLayerProperties$: Observable; - - storageName$ = new ReplaySubject(1); - reservedNames$ = new BehaviorSubject>([]); - - @Input() data: {file: File; content: string; progress: number; configured: boolean; isNumberArray: boolean[]}; - @ViewChild('csv_form_status_stepper', {static: true}) public stepper: MatStepper; - - actualPage$: BehaviorSubject = new BehaviorSubject(null); - - private subscriptions: Array = []; - private header: {value: string}[] = []; - - constructor( - private userService: UserService, - private _changeDetectorRef: ChangeDetectorRef, - public propertiesService: CsvPropertiesService, - ) { - setTimeout(() => this._changeDetectorRef.markForCheck(), 10); - this.isDataProperties$ = this.formStatus$.pipe(map((status) => status === this.FormStatus.DataProperties)); - this.isSpatialProperties$ = this.formStatus$.pipe(map((status) => status === this.FormStatus.SpatialProperties)); - this.isTemporalProperties$ = this.formStatus$.pipe(map((status) => status === this.FormStatus.TemporalProperties)); - this.isTypingProperties$ = this.formStatus$.pipe(map((status) => status === this.FormStatus.TypingProperties)); - this.isLayerProperties$ = this.formStatus$.pipe(map((status) => status === this.FormStatus.LayerProperties)); - - this.userService - .getFeatureDBList() - .pipe(map((entries) => entries.map((entry) => entry.name))) - .subscribe((names) => this.reservedNames$.next(names)); - - this.layerProperties = new FormGroup({ - layerName: new FormControl('', [ - Validators.required, - WaveValidators.notOnlyWhitespace, - layerNameNoDuplicateValidator(this.reservedNames$), - ]), - onError: new FormControl('skip'), - }); - } - - ngOnInit() { - this.propertiesService.changeDataProperties(this.getDataPropertiesDict()); - this.propertiesService.changeSpatialProperties(this.getSpatialPropertiesDict()); - this.propertiesService.changeTemporalProperties(this.getTemporalPropertiesDict()); - this.storageName$.next(this.data.file.name); - this.layerProperties.patchValue({layerName: this.data.file.name}); - this.subscriptions.push( - this.formStatus$.subscribe((status) => { - switch (status) { - case this.FormStatus.DataProperties: - this.dialogTitle = 'CSV Settings'; - this.subtitleDescription = 'Please specify the properties of your CSV file, e.g. the delimiter.'; - break; - case this.FormStatus.SpatialProperties: - this.dialogTitle = 'Spatial Properties'; - this.subtitleDescription = 'In this step you can specify the spatial columns of your CSV file.'; - break; - case this.FormStatus.TemporalProperties: - this.dialogTitle = 'Temporal Properties'; - this.subtitleDescription = 'This step allows you to specify temporal columns of your CSV file.'; - break; - case this.FormStatus.TypingProperties: - this.dialogTitle = 'Typing Properties'; - this.subtitleDescription = 'You can specify the data types of the remaining columns here.'; - break; - case this.FormStatus.LayerProperties: - this.dialogTitle = 'Layer Properties'; - this.subtitleDescription = 'Choose on error behavior and layer name.'; - break; - case this.FormStatus.Loading: - /* falls through */ - default: - break; - } - this.update(10); - setTimeout(() => this.update(10), 10); - }), - this.propertiesService.header$.subscribe((h) => { - this.header = h; - - this.disabledInvalidOptions(); - - // Reorder columns if needed. There might be some columns that are out of range after refactoring delimiters - let arr = [this.spatialProperties.controls['xColumn'].value]; - if (!this.isWkt()) { - arr.push(this.spatialProperties.controls['yColumn'].value); - } - if (this.isTime()) { - arr.push(this.temporalProperties.controls['startColumn'].value); - if ( - [this.IntervalFormat.StartEnd, this.IntervalFormat.StartDur].indexOf( - this.temporalProperties.controls['endColumn'].value, - ) >= 0 - ) { - arr.push(this.temporalProperties.controls['endColumn'].value); - } - } - for (let i = 0; i < arr.length; i++) { - if (arr[i] >= this.header.length) { - this.spatialProperties.controls['xColumn'].setValue(0); - this.spatialProperties.controls['yColumn'].setValue(1); - this.temporalProperties.controls['startColumn'].setValue(2); - this.temporalProperties.controls['endColumn'].setValue(3); - break; - } - } - }), - this.dataProperties.valueChanges.subscribe((data) => { - this.propertiesService.changeDataProperties(this.getDataPropertiesDict()); - }), - this.spatialProperties.valueChanges.subscribe((spatial) => { - this.propertiesService.changeSpatialProperties(this.getSpatialPropertiesDict()); - }), - this.spatialProperties.controls['isWkt'].valueChanges.subscribe((wkt) => { - if (wkt) { - this.spatialProperties.controls['yColumn'].disable(); - this.spatialProperties.controls['wktResultType'].enable(); - this.propertiesService.xyColumn$.next({x: this.propertiesService.xyColumn$.getValue().x}); - this.updateAdmissibilityOfTemporalSpecifications(); - } else { - this.fetchYColumnAndCorrectTemporal(); - } - }), - this.spatialProperties.controls['xColumn'].valueChanges.subscribe((x) => { - if (!this.isWkt()) { - if (x === this.spatialProperties.controls['yColumn'].value) { - if (x === this.header.length - 1) { - this.spatialProperties.controls['yColumn'].setValue(this.spatialProperties.controls['yColumn'].value - 1); - } else { - this.spatialProperties.controls['yColumn'].setValue(this.spatialProperties.controls['yColumn'].value + 1); - } - } - } - this.correctColumns(); - if (!this.isWkt()) { - this.propertiesService.xyColumn$.next({x: x, y: this.spatialProperties.controls['yColumn'].value}); - } else { - this.propertiesService.xyColumn$.next({x: x}); - } - }), - this.spatialProperties.controls['yColumn'].valueChanges.subscribe((y) => { - if (y === this.spatialProperties.controls['xColumn'].value) { - if (y === this.header.length - 1) { - this.spatialProperties.controls['xColumn'].setValue(this.spatialProperties.controls['xColumn'].value - 1); - } else { - this.spatialProperties.controls['xColumn'].setValue(this.spatialProperties.controls['xColumn'].value + 1); - } - } - this.correctColumns(); - if (!this.isWkt()) { - this.propertiesService.xyColumn$.next({x: this.spatialProperties.controls['xColumn'].value, y: y}); - } else { - this.propertiesService.xyColumn$.next({x: this.spatialProperties.controls['xColumn'].value}); - } - }), - this.temporalProperties.valueChanges.subscribe((temporal) => { - this.propertiesService.changeTemporalProperties(this.getTemporalPropertiesDict()); - }), - this.temporalProperties.controls['startColumn'].valueChanges.subscribe((start) => { - if (start === this.temporalProperties.controls['endColumn'].value) { - if (start === this.header.length - 1) { - this.temporalProperties.controls['endColumn'].setValue(this.temporalProperties.controls['endColumn'].value - 1); - } else { - this.temporalProperties.controls['endColumn'].setValue(this.temporalProperties.controls['endColumn'].value + 1); - } - } - if (this.formStatus$.getValue() === this.FormStatus.TemporalProperties) { - this.propertiesService.xyColumn$.next({ - x: start, - y: this.temporalProperties.controls['endColumn'].value, - }); - } - }), - this.temporalProperties.controls['endColumn'].valueChanges.subscribe((end) => { - if (end === this.temporalProperties.controls['startColumn'].value) { - if (end === this.header.length - 1) { - this.temporalProperties.controls['startColumn'].setValue(this.temporalProperties.controls['startColumn'].value - 1); - } else { - this.temporalProperties.controls['startColumn'].setValue(this.temporalProperties.controls['startColumn'].value + 1); - } - } - if (this.formStatus$.getValue() === this.FormStatus.TemporalProperties) { - this.propertiesService.xyColumn$.next({ - x: this.temporalProperties.controls['startColumn'].value, - y: end, - }); - } - }), - this.temporalProperties.controls['isTime'].valueChanges.subscribe((value) => { - if (value === false) { - this.temporalProperties.controls['startColumn'].disable(); - this.temporalProperties.controls['startFormat'].disable(); - this.temporalProperties.controls['endColumn'].disable(); - this.temporalProperties.controls['constantDuration'].disable(); - this.temporalProperties.controls['endFormat'].disable(); - this.temporalProperties.controls['intervalType'].disable(); - } else { - this.temporalProperties.controls['startColumn'].enable(); - this.temporalProperties.controls['startFormat'].enable(); - if (this.temporalProperties.controls['intervalType'].value !== this.IntervalFormat.StartInf) { - this.temporalProperties.controls['endColumn'].enable(); - this.temporalProperties.controls['constantDuration'].enable(); - this.temporalProperties.controls['endFormat'].enable(); - } - this.temporalProperties.controls['intervalType'].enable(); - } - if (this.formStatus$.getValue() === this.FormStatus.TemporalProperties) { - this.propertiesService.xyColumn$.next({ - x: this.temporalProperties.controls['startColumn'].value, - y: this.temporalProperties.controls['endColumn'].value, - }); - } - }), - this.temporalProperties.controls['intervalType'].valueChanges.subscribe((value) => { - if ([IntervalFormat.StartInf].indexOf(value) >= 0 || !this.isTime()) { - this.temporalProperties.controls['endFormat'].disable(); - this.temporalProperties.controls['endColumn'].disable(); - this.temporalProperties.controls['constantDuration'].disable(); - } else { - this.temporalProperties.controls['endFormat'].enable(); - this.temporalProperties.controls['endColumn'].enable(); - this.temporalProperties.controls['constantDuration'].enable(); - if ([IntervalFormat.StartDur, IntervalFormat.StartConst].indexOf(value) >= 0) { - this.temporalProperties.controls['endFormat'].setValue(this.durationFormats[0].value); - } else { - this.temporalProperties.controls['endFormat'].setValue(this.timeFormats[0].value); - } - } - this.temporalProperties.updateValueAndValidity(); - this.update(10); - }), - ); - this.formStatus$.next(this.FormStatus.DataProperties); - this.actualPage$.next(this.dataProperties); - this.propertiesService.changeFormStatus(this.FormStatus.DataProperties); - } - - ngAfterViewInit() { - this.dataProperties.updateValueAndValidity({ - onlySelf: false, - emitEvent: true, - }); - } - - ngOnDestroy() { - this.subscriptions.forEach((sub) => sub.unsubscribe()); - } - - next(event) { - let group: FormGroup; - let status: FormStatus; - switch (event.selectedIndex) { - case 0: - group = this.dataProperties; - status = this.FormStatus.DataProperties; - break; - case 1: - if (!this.isSpatialVisited) { - this.isSpatialVisited = true; - if (this.header.length < 2) { - this.spatialProperties.controls['isWkt'].disable(); - this.spatialProperties.controls['isWkt'].setValue(true); - } - } - group = this.spatialProperties; - status = this.FormStatus.SpatialProperties; - break; - case 2: - group = this.temporalProperties; - status = this.FormStatus.TemporalProperties; - break; - case 3: - group = this.typingProperties; - status = this.FormStatus.TypingProperties; - break; - case 4: - group = this.layerProperties; - status = this.FormStatus.LayerProperties; - group.controls['layerName'].updateValueAndValidity(); - break; - } - this.propertiesService.changeFormStatus(status); - this.actualPage$.next(group); - this.formStatus$.next(status); - if (status === this.FormStatus.TemporalProperties) { - this.propertiesService.xyColumn$.next({ - x: this.temporalProperties.controls['startColumn'].value, - y: this.temporalProperties.controls['endColumn'].value, - }); - } - if (status === this.FormStatus.SpatialProperties) { - this.propertiesService.xyColumn$.next({ - x: this.spatialProperties.controls['xColumn'].value, - y: this.spatialProperties.controls['yColumn'].value, - }); - } - this.update(100); - } - - update(timeOut: number) { - setTimeout(() => { - this._changeDetectorRef.reattach(); - }, timeOut); - } - - correctColumns() { - if (this.temporalProperties.controls['isTime'].disabled) { - return; - } - let direction = 1; - let arr = [this.spatialProperties.controls['xColumn'].value]; - if (!this.isWkt()) { - arr.push(this.spatialProperties.controls['yColumn'].value); - } - if (!this.temporalProperties.controls['endColumn'].disabled) { - arr.push(this.temporalProperties.controls['endColumn'].value); - } - while (arr.indexOf(this.temporalProperties.controls['startColumn'].value) >= 0) { - if (this.temporalProperties.controls['startColumn'].value === 0) { - direction = 1; - } else if (this.temporalProperties.controls['startColumn'].value === this.header.length - 1) { - direction = -1; - } - this.temporalProperties.controls['startColumn'].setValue(this.temporalProperties.controls['startColumn'].value + direction, { - emitEvent: false, - }); - } - this.temporalProperties.updateValueAndValidity(); - if (!this.temporalProperties.controls['endColumn'].disabled) { - direction = 1; - arr = [ - this.spatialProperties.controls['xColumn'].value, - this.spatialProperties.controls['yColumn'].value, - this.temporalProperties.controls['startColumn'].value, - ]; - while (arr.indexOf(this.temporalProperties.controls['endColumn'].value) >= 0) { - if (this.temporalProperties.controls['endColumn'].value === 0) { - direction = 1; - } else if (this.temporalProperties.controls['endColumn'].value === this.header.length - 1) { - direction = -1; - } - this.temporalProperties.controls['endColumn'].setValue(this.temporalProperties.controls['endColumn'].value + direction, { - emitEvent: false, - }); - } - } - this.temporalProperties.updateValueAndValidity(); - } - - updateAdmissibilityOfTemporalSpecifications() { - let requiredColumns = this.isWkt() ? 1 : 2; - if (this.header.length <= requiredColumns) { - this.temporalProperties.controls['isTime'].setValue(false); - this.temporalProperties.controls['isTime'].disable(); - } else if (this.header.length <= requiredColumns + 1) { - if ([IntervalFormat.StartEnd, IntervalFormat.StartDur].indexOf(this.temporalProperties.controls['intervalType'].value) >= 0) { - this.temporalProperties.controls['intervalType'].setValue(IntervalFormat.StartInf); - } - this.temporalProperties.controls['isTime'].enable(); - this.temporalProperties.controls['startColumn'].setValue(0); - this.correctColumns(); - } else { - this.temporalProperties.controls['isTime'].enable(); - this.temporalProperties.controls['startColumn'].setValue(0); - this.temporalProperties.controls['endColumn'].setValue(0); - this.correctColumns(); - } - this._changeDetectorRef.detectChanges(); - } - - fetchYColumnAndCorrectTemporal() { - this.updateAdmissibilityOfTemporalSpecifications(); - let x = this.spatialProperties.controls['xColumn'].value; - if ( - this.spatialProperties.controls['yColumn'].value < 0 || - this.spatialProperties.controls['yColumn'].value >= this.header.length - ) { - for (let i = 0; i < this.header.length; i++) { - if (i !== this.spatialProperties.controls['xColumn'].value) { - this.spatialProperties.controls['yColumn'].setValue(i); - break; - } - } - } - this.spatialProperties.controls['yColumn'].enable(); - this.spatialProperties.controls['xColumn'].setValue(x); - this.spatialProperties.controls['wktResultType'].disable(); - this.propertiesService.xyColumn$.next({ - x: this.spatialProperties.controls['xColumn'].value, - y: this.spatialProperties.controls['yColumn'].value, - }); - } - - noAvailableColumnsForTimeSpecification(isWkt: boolean, requiredColumns: number): boolean { - return (isWkt ? 1 : 2) + requiredColumns > this.header.length; - } - - isWkt(): boolean { - return this.spatialProperties.controls['isWkt'].value; - } - - isTime(): boolean { - return this.temporalProperties.controls['isTime'].value; - } - - disabledInvalidOptions() { - if (this.header.length < 2 && this.isSpatialVisited) { - this.spatialProperties.controls['isWkt'].disable(); - this.spatialProperties.controls['isWkt'].setValue(true); - } else { - this.spatialProperties.controls['isWkt'].enable(); - } - this.updateAdmissibilityOfTemporalSpecifications(); - } - - getDataPropertiesDict(): DataPropertiesDict { - return { - delimiter: this.dataProperties.controls['delimiter'].value, - decimalSeparator: this.dataProperties.controls['decimalSeparator'].value, - isTextQualifier: this.dataProperties.controls['isTextQualifier'].value, - textQualifier: this.dataProperties.controls['textQualifier'].value, - isHeaderRow: this.dataProperties.controls['isHeaderRow'].value, - headerRow: this.dataProperties.controls['headerRow'].value, - }; - } - - getSpatialPropertiesDict(): SpatialPropertiesDict { - return { - xColumn: this.spatialProperties.controls['xColumn'].value, - yColumn: this.spatialProperties.controls['yColumn'].value, - spatialReferenceSystem: this.spatialProperties.controls['spatialReferenceSystem'].value, - coordinateFormat: this.spatialProperties.controls['coordinateFormat'].value, - isWkt: this.isWkt(), - wktResultType: this.spatialProperties.controls['wktResultType'].value, - }; - } - - getTemporalPropertiesDict(): TemporalPropertiesDict { - return { - intervalType: this.temporalProperties.controls['intervalType'].value, - isTime: this.isTime(), - startColumn: this.temporalProperties.controls['startColumn'].value, - startFormat: this.temporalProperties.controls['startFormat'].value, - endColumn: this.temporalProperties.controls['endColumn'].value, - endFormat: this.temporalProperties.controls['endFormat'].value, - constantDuration: this.temporalProperties.controls['constantDuration'].value, - }; - } - - get xColumnName(): string { - if (this.isWkt()) { - return ''; - } else { - return this.spatialProperties.controls['spatialReferenceSystem'].value.xCoordinateName + '-'; - } - } - - get isValid(): boolean { - return ( - this.dataProperties.valid && - this.spatialProperties.valid && - this.temporalProperties.valid && - this.typingProperties.valid && - this.layerProperties.valid - ); - } -} -export function layerNameNoDuplicateValidator(reservedNames: BehaviorSubject>): ValidatorFn { - return (control: AbstractControl): {[key: string]: any} => { - return reservedNames.getValue().indexOf(control.value) < 0 - ? null - : {layerNameNoDuplicate: {value: 'Layer name already in use ' + control.value}}; - }; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-table/csv-table-template.component.html b/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-table/csv-table-template.component.html deleted file mode 100644 index 825e8ceb..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-table/csv-table-template.component.html +++ /dev/null @@ -1,125 +0,0 @@ -
    -
    - - - - - - - -
    - - - Text - Number - - -

    Coordinate

    -

    - Coordinate -

    -

    - Time -

    -

    - Time -

    -
    -
    -
    -
    - - - - - - - - - - - - - - - - -
    - {{ h.value }} - - - - -
    -
    -
    -
    - - - - - - - - -
    - {{ e }} -
    -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-table/csv-table.component.scss b/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-table/csv-table.component.scss deleted file mode 100644 index 69b35088..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-table/csv-table.component.scss +++ /dev/null @@ -1,212 +0,0 @@ -$latitudeColor: #26c5ff; -$longitudeColor: orange; -$startColor: darkgreen; -$endColor: darkviolet; -$backgroundColor: var(--wave-primary-color, grey); -$titleColor: white; /*Inherit from theme here.*/ - -div.latitudeSelector mat-select ::ng-deep span.mat-select-placeholder { - color: $latitudeColor; -} - -div.longitudeSelector mat-select ::ng-deep span.mat-select-placeholder { - color: $longitudeColor; -} - -div.startSelector mat-select ::ng-deep span.mat-select-placeholder { - color: $startColor; -} - -div.endSelector mat-select ::ng-deep span.mat-select-placeholder { - color: $endColor; -} - -div.constantSelector mat-form-field ::ng-deep span.mat-input-placeholder { - color: $endColor; -} - -.custom mat-form-field ::ng-deep label.mat-input-placeholder { - color: $titleColor; - opacity: 0.75; -} - -.table-frame { - text-align: left; - font-size: 0; - max-width: 75vw; - display: inline-block; - overflow: hidden; - margin-left: auto; - margin-right: auto; - border: solid 1px darkgray; -} - -.table-frame br { - display: none; -} - -.typingdiv { - max-width: 100%; - font-size: 15px; - display: block; - overflow: hidden; - border-bottom: solid 1px dimgray; - background-color: #ffffff; - font-weight: 300; -} - -.headerdiv { - max-width: 100%; - display: block; - overflow: hidden; - border-bottom: solid 1px dimgray; - border-right: solid 1px dimgray; - margin-bottom: 0; - background-color: $backgroundColor; - color: $titleColor; - font-size: 15px; - font-weight: 300; -} - -.headerdiv table td.custom mat-form-field { - margin-bottom: 0; - padding-bottom: 0; - font-size: 15px; - height: 30px; - color: $titleColor; -} - -td { - max-width: 500px; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - -.bodydiv { - max-width: 100%; - font-size: 15px; - display: block; - overflow-x: auto; - overflow-y: hidden; -} - -.bodydiv table tr:nth-child(even) { - background-color: #add4f4; /*Take background color and mix with white.*/ -} - -.resizeTable { - display: table; - table-layout: fixed; -} - -.custom { - font-weight: normal; - padding-bottom: 0; - margin-bottom: 0; -} - -.scrollbar-measure { - width: 100px; - height: 100px; - overflow: scroll; - position: absolute; - top: -9999px; -} - -.time_green { - border: solid $startColor; - border-radius: 5px; - text-align: center; - margin-top: 3px; - margin-bottom: 3px; - horiz-align: center; -} - -.time_violet { - border: solid $endColor; - border-radius: 5px; - text-align: center; - margin-top: 3px; - margin-bottom: 3px; - horiz-align: center; -} - -.coordinate_orange { - border: solid $longitudeColor; - border-radius: 5px; - text-align: center; - margin-top: 3px; - margin-bottom: 3px; - horiz-align: center; -} - -.coordinate_blue { - border: solid $latitudeColor; - border-radius: 5px; - text-align: center; - margin-top: 3px; - margin-bottom: 3px; - horiz-align: center; -} - -/**Column Colors*/ -td.orange { - border-left-style: solid; - border-right-style: solid; - border-color: $longitudeColor; -} - -td.blue { - border-left-style: solid; - border-right-style: solid; - border-color: $latitudeColor; -} - -td.green { - border-left-style: solid; - border-right-style: solid; - border-color: $startColor; -} - -td.violet { - border-left-style: solid; - border-right-style: solid; - border-color: $endColor; -} - -.orangeHead { - border-left-style: solid; - border-right-style: solid; - border-top-style: solid; - border-color: $longitudeColor; - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} - -.blueHead { - border-left-style: solid; - border-right-style: solid; - border-top-style: solid; - border-color: $latitudeColor; - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} - -.greenHead { - border-left-style: solid; - border-right-style: solid; - border-top-style: solid; - border-color: $startColor; - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} - -.violetHead { - border-left-style: solid; - border-right-style: solid; - border-top-style: solid; - border-color: $endColor; - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-table/csv-table.component.ts b/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-table/csv-table.component.ts deleted file mode 100644 index 0ba982e9..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-config/csv-table/csv-table.component.ts +++ /dev/null @@ -1,374 +0,0 @@ -import {map} from 'rxjs/operators'; -/** - * Created by Julian on 09/05/2017. - */ -import {IntervalFormat} from '../../interval.enum'; -import { - Component, - ChangeDetectionStrategy, - Input, - ViewChild, - ElementRef, - OnInit, - AfterViewInit, - ChangeDetectorRef, - OnDestroy, -} from '@angular/core'; -import {DataPropertiesDict, FormStatus} from '../csv-properties/csv-properties.component'; -import * as Papa from 'papaparse'; -import {Observable, Subscription, BehaviorSubject} from 'rxjs'; -import {UploadData} from '../../csv-upload/csv-upload.component'; -import {CsvPropertiesService} from '../../csv-dialog/csv.properties.service'; - -export const HEADER_TABLE_ID = 'CSV_TABLE_HEADER_TABLE', - HEADER_DIV_ID = 'CSV_TABLE_HEADER_DIV', - BODY_TABLE_ID = 'CSV_TABLE_BODY_TABLE', - BODY_DIV_ID = 'CSV_TABLE_BODY_DIV', - TYPING_TABLE_ID = 'CSV_TABLE_TYPING_TABLE', - TYPING_DIV_ID = 'CSV_TABLE_TYPING_DIV', - TABLE_FRAME_ID = 'CSV_TABLE_TABLE_FRAME'; - -@Component({ - selector: 'wave-csv-table', - templateUrl: './csv-table-template.component.html', - styleUrls: ['./csv-table.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class CsvTableComponent implements OnInit, AfterViewInit, OnDestroy { - HEADER_TABLE_ID = HEADER_TABLE_ID; - HEADER_DIV_ID = HEADER_DIV_ID; - BODY_TABLE_ID = BODY_TABLE_ID; - BODY_DIV_ID = BODY_DIV_ID; - TYPING_TABLE_ID = TYPING_TABLE_ID; - TYPING_DIV_ID = TYPING_DIV_ID; - TABLE_FRAME_ID = TABLE_FRAME_ID; - - @Input() data: UploadData; - @Input() cellSpacing: number; - @Input() linesToParse: number; - - IntervalFormat = IntervalFormat; - isNumberArray: number[]; - untypedColumns: BehaviorSubject; - isWkt: BehaviorSubject; - - @ViewChild(HEADER_DIV_ID, {static: true}) headerDiv: ElementRef; - @ViewChild(BODY_DIV_ID, {static: true}) bodyDiv: ElementRef; - @ViewChild(TYPING_DIV_ID) typingDiv: ElementRef; - @ViewChild(HEADER_TABLE_ID, {static: true}) headerTable: ElementRef; - @ViewChild(BODY_TABLE_ID, {static: true}) bodyTable: ElementRef; - @ViewChild(TYPING_TABLE_ID) typingTable: ElementRef; - @ViewChild(TABLE_FRAME_ID, {static: true}) tableFrame: ElementRef; - - parsedData: Array>; - customHeader: {value: string}[] = []; - header: {value: string}[] = []; - elements: string[][] = []; - cellSizes: number[] = []; - dataProperties: DataPropertiesDict; - formStatus: FormStatus; - maxColumnWidth = 500; - - isDataProperties$: Observable; - isSpatialProperties$: Observable; - isTemporalProperties$: Observable; - isTypingProperties$: Observable; - isLayerProperties$: Observable; - - xColumn$: Observable; - yColumn$: Observable; - - private subscriptions: Array = []; - - constructor(public _changeDetectorRef: ChangeDetectorRef, public propertiesService: CsvPropertiesService) { - this.isDataProperties$ = this.propertiesService.formStatus$.pipe(map((status) => status === FormStatus.DataProperties)); - this.isSpatialProperties$ = this.propertiesService.formStatus$.pipe(map((status) => status === FormStatus.SpatialProperties)); - this.isTemporalProperties$ = this.propertiesService.formStatus$.pipe(map((status) => status === FormStatus.TemporalProperties)); - this.isTypingProperties$ = this.propertiesService.formStatus$.pipe(map((status) => status === FormStatus.TypingProperties)); - this.isLayerProperties$ = this.propertiesService.formStatus$.pipe(map((status) => status === FormStatus.LayerProperties)); - this.xColumn$ = this.propertiesService.xyColumn$.pipe(map((xy) => xy.x)); - this.yColumn$ = this.propertiesService.xyColumn$.pipe(map((xy) => xy.y)); - - setTimeout(() => this._changeDetectorRef.markForCheck(), 0); // FIXME: update to Angular 7 -> changed to lambda, 0 - this.untypedColumns = new BehaviorSubject([ - this.propertiesService.xyColumn$.getValue().x, - this.propertiesService.xyColumn$.getValue().y, - ]); - this.isWkt = new BehaviorSubject(false); - } - - ngOnInit() { - this.subscriptions.push( - this.propertiesService.dataProperties$.subscribe((data) => { - if (!!this.dataProperties) { - if (this.dataProperties.isHeaderRow !== data.isHeaderRow) { - if (data.isHeaderRow === true) { - this.customHeader = new Array(this.elements[0].length); - for (let i = 0; i < this.header.length; i++) { - this.customHeader[i] = this.header[i]; - } - } else { - if (this.customHeader.length === this.elements[0].length) { - for (let i = 0; i < this.customHeader.length; i++) { - this.header[i] = this.customHeader[i]; - } - } else { - this.customHeader = new Array(this.elements[0].length); - this.header = new Array(this.elements[0].length); - for (let i = 0; i < this.customHeader.length; i++) { - this.header[i] = {value: ''}; - this.customHeader[i] = {value: ''}; - } - } - } - } - } - this.dataProperties = data; - this.parse(); - if (this.header.length > 0) { - setTimeout(() => this.resize(), 0); // FIXME: update to Angular 7 -> changed to lambda, 0 - } - }), - this.propertiesService.formStatus$.subscribe((formStatus) => { - if ([formStatus, this.formStatus].indexOf(FormStatus.TypingProperties) >= 0) { - this.resize(); - this.bodyScroll(); - } - this.formStatus = formStatus; - }), - this.propertiesService.spatialProperties$.subscribe((data) => { - let untypedColumns = [data.xColumn]; - if (!data.isWkt) { - untypedColumns.push(data.yColumn); - } - let c = this.isWkt.getValue() ? 1 : 0; - for (let i = 2 - c; i < this.untypedColumns.getValue().length; i++) { - untypedColumns.push(this.untypedColumns.getValue()[i]); - } - this.untypedColumns.next(untypedColumns); - this.isWkt.next(data.isWkt); - this.update(10); - }), - this.propertiesService.temporalProperties$.subscribe((data) => { - let untypedColumns = [this.untypedColumns.getValue()[0]]; - if (!this.isWkt.getValue()) { - untypedColumns.push(this.untypedColumns.getValue()[1]); - } - if (data.isTime) { - untypedColumns.push(data.startColumn); - if ([IntervalFormat.StartEnd, IntervalFormat.StartDur].indexOf(data.intervalType) >= 0) { - untypedColumns.push(data.endColumn); - } - } - this.untypedColumns.next(untypedColumns); - this.update(10); - }), - // this.resizeEvent$.subscribe(data => this.resizeTableFrame()) - ); - this.parse(); - this.cellSizes = new Array(this.header.length); - for (let i = 0; i < this.header.length; i++) { - this.cellSizes[i] = 0; - } - } - - ngAfterViewInit() { - this.resize(); - } - - ngOnDestroy() { - this.subscriptions.forEach((sub) => sub.unsubscribe()); - } - - parse() { - if (!!this.dataProperties) { - let textQualifier: string = this.dataProperties.isTextQualifier ? this.dataProperties.textQualifier : null; - let prev: number = this.dataProperties.isHeaderRow ? this.dataProperties.headerRow + this.linesToParse + 1 : this.linesToParse; - let parsed = Papa.parse( - this.data.content as string, - { - delimiter: this.dataProperties.delimiter, - newline: '', - quoteChar: textQualifier, - header: false, - skipEmptyLines: true, - preview: prev, - } as any, - ); - this.parsedData = parsed.data; - // this.csvProperty.dataProperties.controls['delimiter'].setValue(parsed.meta.delimiter, {emitEvent: false}); - if (this.dataProperties.isHeaderRow) { - this.header = new Array(this.parsedData[this.dataProperties.headerRow].length); - for (let i = 0; i < this.header.length; i++) { - this.header[i] = {value: this.parsedData[this.dataProperties.headerRow][i]}; - } - this.elements = this.parsedData.slice( - this.dataProperties.headerRow + 1, - this.dataProperties.headerRow + this.linesToParse + 1, - ); - } else { - this.elements = this.parsedData; - if (this.header.length !== this.elements[0].length) { - this.header = new Array(this.elements[0].length); - for (let i = 0; i < this.header.length; i++) { - this.header[i] = {value: ''}; - } - } - } - if (!this.header || !this.elements) { - console.log('to large data'); - } - this.resetNumberArr(); - this.propertiesService.changeHeader(this.header); - // TODO: set Start/End column to a valid value, if it exceeds header length. - } - } - - resetNumberArr() { - this.isNumberArray = new Array(this.header.length); - this.isNumberArray.fill(0, 0, this.header.length); - } - - /**Gets called on table property changes. Resets the min-width property of the first rows cells to 0. - * Causes a reload "effect" - */ - resetTableSize() { - this.cellSizes = []; - for (let i = 0; i < 2 * Math.max(this.header.length, this.elements.length); i++) { - this.cellSizes.push(0); - } - } - - /**Gets called on table property change with some delay, so the view can reload first. - * Sets the min-width property of every tables first rows cells to the maximum - * of every tables first rows cells(Column-wise), - * if table assigned to class "resizeTable". - */ - resizeTable() { - let tableArr: HTMLTableElement[] = []; - tableArr.push(this.headerTable.nativeElement); - tableArr.push(this.bodyTable.nativeElement); - if (this.headerTable.nativeElement === null) { - return; - } - if (this.formStatus === FormStatus.TypingProperties) { - tableArr.push(this.typingTable.nativeElement); - } - let colNumber = 0; - for (let t of tableArr) { - if (t.rows.length > colNumber) { - colNumber = t.rows.length; - } - } - for (let t of tableArr) { - // t.style.borderSpacing = this.cellSpacing + 'px 0'; - let row: HTMLTableRowElement = t.rows.item(0) as HTMLTableRowElement; - for (let j = 0; j < row.cells.length; j++) { - let cell: HTMLElement = row.cells.item(j) as HTMLElement; - if (cell.getAttribute('name') === 'spacer') { - this.cellSizes[j] = this.cellSpacing; - } else if (!this.cellSizes[j] || this.cellSizes[j] < cell.getBoundingClientRect().width) { - this.cellSizes[j] = cell.getBoundingClientRect().width; - } - } - } - // this.resizeTableFrame(); - // Reset the headerdiv to body divs scroll. - this.headerDiv.nativeElement.scrollLeft = this.bodyDiv.nativeElement.scrollLeft = 0; - if (this.formStatus === FormStatus.TypingProperties) { - this.typingDiv.nativeElement.scrollLeft = this.bodyDiv.nativeElement.scrollLeft; - } - } - - bodyScroll() { - let scrollLeft = this.bodyDiv.nativeElement.scrollLeft; - this.headerDiv.nativeElement.scrollLeft = scrollLeft; - if (this.formStatus === FormStatus.TypingProperties) { - this.typingDiv.nativeElement.scrollLeft = scrollLeft; - } - } - - headerScroll() { - let scrollLeft = this.headerDiv.nativeElement.scrollLeft; - this.bodyDiv.nativeElement.scrollLeft = scrollLeft; - if (this.formStatus === FormStatus.TypingProperties) { - this.typingDiv.nativeElement.scrollLeft = scrollLeft; - } - } - - /**Gets called on window size changes. - * It brings the table container back to its initial 80%. This is a bug fix. - */ - resizeTableFrame() { - let tableArr: Element[] = []; - tableArr.push(this.headerTable.nativeElement); - tableArr.push(this.bodyTable.nativeElement); - if (this.formStatus === FormStatus.TypingProperties) { - tableArr.push(this.typingTable.nativeElement); - } - let width = 0; - for (let t of tableArr) { - width = Math.max(width, t.clientWidth); - } - this.tableFrame.nativeElement.style.maxWidth = Math.min(window.innerWidth * 0.8 - 2 * 24, width) + 'px'; - this.tableFrame.nativeElement.style.minWidth = Math.min(window.innerWidth * 0.8 - 2 * 24, width) + 'px'; - // innerWidth * 0.8 = 80vw(max größe vom dialog) -24 ist padding von mat-dialog-content. - } - - /**Resets table size and delays then. - * After delay(so view can reload on resetted table column sizes) resizes table to maximum of every table. - */ - resize() { - this.resetTableSize(); - this.update(10); - setTimeout(() => this.resizeTable(), 100); - this.update(100); - } - - ending(i: number): string { - if ((i - 1) % 10 === 0 && (i - 11) % 100 !== 0) { - return 'st'; - } else if ((i - 2) % 10 === 0 && (i - 12) % 100 !== 0) { - return 'nd'; - } else if ((i - 3) % 10 === 0 && (i - 13) % 100 !== 0) { - return 'rd'; - } else { - return 'th'; - } - } - - update(timeOut: number) { - setTimeout(() => { - this._changeDetectorRef.markForCheck(); - }, timeOut); - } - - styleDict(i: number, isSpatial: boolean, isTemporal: boolean, head: boolean) { - let j = this.untypedColumns.getValue().indexOf(i); - if (isSpatial) { - if (head) { - return {orangeHead: j === 0, blueHead: j === 1 && !this.isWkt.getValue()}; - } else { - return {orange: j === 0, blue: j === 1 && !this.isWkt.getValue()}; - } - } - if (isTemporal) { - let c = this.isWkt.getValue() ? 1 : 0; - if (head) { - return {greenHead: j === 2 - c, violetHead: j === 3 - c}; - } else { - return {green: j === 2 - c, violet: j === 3 - c}; - } - } - return {}; - } - - get notOnlyWhiteSpace(): boolean { - for (let h of this.header) { - if (h.value === '' || h.value === null || h.value === undefined) { - return false; - } - } - return true; - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv-dialog.component.html b/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv-dialog.component.html deleted file mode 100644 index 04e78f42..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv-dialog.component.html +++ /dev/null @@ -1,46 +0,0 @@ -CSV Upload - - -
    - - -
    - - - -
    - - -
    - - - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv-dialog.component.scss b/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv-dialog.component.scss deleted file mode 100644 index e7ccd98d..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv-dialog.component.scss +++ /dev/null @@ -1,14 +0,0 @@ -mat-dialog-content { - padding-top: 1rem; -} - -mat-spinner { - width: 25%; - height: auto; - margin: 1rem auto; -} - -wave-csv-table { - margin-left: auto; - margin-right: auto; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv-dialog.component.ts b/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv-dialog.component.ts deleted file mode 100644 index be79cc79..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv-dialog.component.ts +++ /dev/null @@ -1,258 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy, ViewChild, Inject} from '@angular/core'; -import {UploadData} from '../csv-upload/csv-upload.component'; -import {CsvSourceType, CSVParameters} from '../../../types/csv-source-type.model'; -import {Operator} from '../../../operator.model'; -import {ResultTypes} from '../../../result-type.model'; -import {UserService} from '../../../../users/user.service'; -import {AbstractVectorSymbology, PointSymbology, VectorSymbology} from '../../../../layers/symbology/symbology.model'; -import {VectorLayer} from '../../../../layers/layer.model'; -import {RandomColorService} from '../../../../util/services/random-color.service'; -import {MatDialogRef, MatDialog, MAT_DIALOG_DATA} from '@angular/material/dialog'; -import {BehaviorSubject} from 'rxjs'; -import {Projections} from '../../../projection.model'; -import {CsvPropertiesService} from './csv.properties.service'; -import {ProjectService} from '../../../../project/project.service'; -import {IntervalFormat} from '../interval.enum'; -import {CsvPropertiesComponent} from '../csv-config/csv-properties/csv-properties.component'; -import {CsvTableComponent} from '../csv-config/csv-table/csv-table.component'; -import {HttpErrorResponse} from '@angular/common/http'; - -@Component({ - selector: 'wave-csv-dialog', - templateUrl: './csv-dialog.component.html', - styleUrls: ['./csv-dialog.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - providers: [CsvPropertiesService], -}) -export class CsvDialogComponent implements OnInit { - IntervalFormat = IntervalFormat; - @ViewChild(CsvPropertiesComponent) csvProperties; - @ViewChild(CsvTableComponent) csvTable; - data: UploadData; - uploading$ = new BehaviorSubject(false); - - constructor( - private userService: UserService, - private randomColorService: RandomColorService, - private projectService: ProjectService, - private dialogRef: MatDialogRef, - private errorDialog: MatDialog, - ) {} - - ngOnInit() {} - - submit() { - this.uploading$.next(true); - const untypedCols = this.csvTable.untypedColumns.getValue(); - // TODO: refactor most of this - const fieldSeparator = this.csvProperties.dataProperties.controls['delimiter'].value; - const geometry = this.csvProperties.spatialProperties.controls['isWkt'].value ? 'wkt' : 'xy'; - const time = this.intervalString; - const time1Format = this.csvProperties.temporalProperties.controls['startFormat'].value; - const time2Format = this.csvProperties.temporalProperties.controls['endFormat'].value; - const header = new Array(this.csvTable.header.length); - for (let i = 0; i < this.csvTable.header.length; i++) { - header[i] = this.csvTable.header[i].value; - } - const columnX = header[this.csvProperties.spatialProperties.controls['xColumn'].value]; - const columnY = this.csvProperties.spatialProperties.controls['isWkt'].value - ? '' - : header[this.csvProperties.spatialProperties.controls['yColumn'].value]; - const time1 = this.csvProperties.temporalProperties.controls['isTime'].value - ? header[this.csvProperties.temporalProperties.controls['startColumn'].value] - : ''; - const time2 = this.csvProperties.temporalProperties.controls['isTime'].value - ? header[this.csvProperties.temporalProperties.controls['endColumn'].value] - : ''; - const numericColumns = header.filter((name, index) => { - return this.csvTable.isNumberArray[index] === 1 && untypedCols.indexOf(index) < 0; - }); - const textualColumns = header.filter((name, index) => { - return this.csvTable.isNumberArray[index] === 0 && untypedCols.indexOf(index) < 0; - }); - const onError = this.csvProperties.layerProperties.controls['onError'].value; - const columns = this.csvProperties.spatialProperties.controls['isWkt'].value - ? { - x: columnX, - numeric: numericColumns, - textual: textualColumns, - } - : { - x: columnX, - y: columnY, - numeric: numericColumns, - textual: textualColumns, - }; - const parameters: CSVParameters = { - fieldSeparator, - geometry, - time: - time.indexOf('constant') < 0 - ? (time as 'none' | 'start+inf' | 'start+end' | 'start+duration' | {use: 'start'; duration: number}) - : {use: 'start', duration: this.csvProperties.temporalProperties.controls['constantDuration'].value}, - header: this.csvProperties.dataProperties.controls['isHeaderRow'].value ? null : header, - columns, - onError, - }; - - // filter out geo columns - function removeIfExists(array: Array, name: string) { - const index = array.indexOf(name); - if (index >= 0) { - array.splice(index, 1); - } - } - - removeIfExists(parameters.columns.textual, columnX); - removeIfExists(parameters.columns.numeric, columnX); - if (this.csvProperties.spatialProperties.controls['isWkt'].value) { - removeIfExists(parameters.columns.textual, columnY); - removeIfExists(parameters.columns.numeric, columnY); - } - if (time !== 'none') { - parameters.timeFormat = { - time1: { - format: 'custom', - customFormat: time1Format, - }, - }; - parameters.columns.time1 = time1; - - removeIfExists(parameters.columns.textual, time1); - removeIfExists(parameters.columns.numeric, time1); - - if (time.indexOf('end') >= 0) { - parameters.timeFormat.time2 = { - format: 'custom', - customFormat: time2Format, - }; - parameters.columns.time2 = time2; - - removeIfExists(parameters.columns.textual, time2); - removeIfExists(parameters.columns.numeric, time2); - } - if (time.indexOf('duration') >= 0) { - // TODO: refactor for other formats - parameters.timeFormat.time2 = { - format: time2Format as 'seconds', - }; - parameters.columns.time2 = time2; - - removeIfExists(parameters.columns.textual, time2); - removeIfExists(parameters.columns.numeric, time2); - } - } - - const csvSourceType = new CsvSourceType({ - dataURI: 'data:text/plain,' + this.data.content, - parameters, - }); - - const operator = new Operator({ - operatorType: csvSourceType, - resultType: this.csvProperties.spatialProperties.controls['isWkt'].value - ? this.csvProperties.spatialProperties.controls['wktResultType'].value - : ResultTypes.POINTS, - projection: this.csvProperties.spatialProperties.controls['spatialReferenceSystem'].value, - }).getProjectedOperator(Projections.WGS_84); - this.uploading$.next(true); - - this.userService.addFeatureToDB(this.csvProperties.layerProperties.controls['layerName'].value, operator).subscribe( - (data) => { - // Regular query processing - this.addLayer(data); - - this.dialogRef.close(); - }, - (error) => { - // Error code - open dialog - this.uploading$.next(false); - this.openErrorDialog(error); - }, - ); - } - - private addLayer(entry: {name: string; operator: Operator}) { - const color = this.randomColorService.getRandomColorRgba(); - let symbology: AbstractVectorSymbology; - let clustered: boolean; - - if (entry.operator.resultType === ResultTypes.POINTS) { - symbology = PointSymbology.createClusterSymbology({ - fillRGBA: color, - }); - clustered = true; - } else { - symbology = VectorSymbology.createSymbology({ - fillRGBA: color, - }); - clustered = false; - } - - const layer = new VectorLayer({ - name: entry.name, - operator: entry.operator, - symbology, - // data: this.mappingQueryService.getWFSDataStreamAsGeoJsonFeatureCollection({ - // operator: entry.operator, - // clustered: clustered, - // }), - // provenance: this.mappingQueryService.getProvenanceStream(entry.operator), - clustered, - }); - // this.layerService.addLayer(layer); - this.projectService.addLayer(layer); - } - - openErrorDialog(error: HttpErrorResponse): void { - const errorDialogRef = this.errorDialog.open(CsvErrorDialogComponent, { - width: '400px', - data: {error}, - }); - errorDialogRef.afterClosed().subscribe((result) => { - if (result) { - this.dialogRef.close(); - } - this.uploading$.next(false); - }); - } - - get intervalString(): string { - if (!this.csvProperties.temporalProperties.controls['isTime'].value) { - return 'none'; - } - switch (this.csvProperties.temporalProperties.controls['intervalType'].value) { - case IntervalFormat.StartInf: - return 'start+inf'; - case IntervalFormat.StartEnd: - return 'start+end'; - case IntervalFormat.StartDur: - return 'start+duration'; - case IntervalFormat.StartConst: - return 'start+constant'; - default: - return 'none'; - } - } -} - -@Component({ - selector: 'wave-csv-dialog-error-dialog', - template: ` - {{ data.error.name }} -
    - {{ data.error.url }}:
    - {{ data.error.status }} - {{ data.error.statusText }} -
    - - - - - `, -}) -export class CsvErrorDialogComponent { - constructor( - public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: {error: HttpErrorResponse}, - ) {} -} diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv.properties.service.ts b/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv.properties.service.ts deleted file mode 100644 index c795f92a..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-dialog/csv.properties.service.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { - DataPropertiesDict, - FormStatus, - SpatialPropertiesDict, - TemporalPropertiesDict, -} from '../csv-config/csv-properties/csv-properties.component'; -import {Subject, BehaviorSubject, Subscription, Observable} from 'rxjs'; -import {Injectable} from '@angular/core'; - -@Injectable() -export class CsvPropertiesService { - private dataProperties = new BehaviorSubject({ - delimiter: ',', - decimalSeparator: '.', - isTextQualifier: true, - textQualifier: '"', - isHeaderRow: true, - headerRow: 0, - }); - private spatialProperties = new BehaviorSubject({ - xColumn: -1, - yColumn: -1, - spatialReferenceSystem: null, - coordinateFormat: '', - isWkt: false, - wktResultType: null, - }); - private temporalProperties = new BehaviorSubject({ - intervalType: null, - isTime: false, - startColumn: -1, - startFormat: '', - endColumn: -1, - endFormat: '', - constantDuration: 0, - }); - private header = new BehaviorSubject<{value: string}[]>([]); - private formStatus = new BehaviorSubject(null); - - xyColumn$: BehaviorSubject<{x: number; y?: number}> = new BehaviorSubject<{x: number; y?: number}>({x: 0, y: 0}); - - dataProperties$ = this.dataProperties.asObservable(); - spatialProperties$ = this.spatialProperties.asObservable(); - temporalProperties$ = this.temporalProperties.asObservable(); - header$ = this.header.asObservable(); - formStatus$ = this.formStatus.asObservable(); - - public changeDataProperties(p: DataPropertiesDict) { - this.dataProperties.next(p); - } - - public changeSpatialProperties(s: SpatialPropertiesDict) { - this.spatialProperties.next(s); - } - - public changeTemporalProperties(t: TemporalPropertiesDict) { - this.temporalProperties.next(t); - } - - public changeHeader(h: {value: string}[]) { - this.header.next(h); - } - - public changeFormStatus(fs: FormStatus) { - this.formStatus.next(fs); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-upload/csv-upload-style.component.css b/projects/wave-core/src/lib/operators/dialogs/csv/csv-upload/csv-upload-style.component.css deleted file mode 100644 index a62a5bda..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-upload/csv-upload-style.component.css +++ /dev/null @@ -1,17 +0,0 @@ -.file-upload { - position: relative; - overflow: hidden; - margin: 10px; -} - -.file-upload input.file-input { - position: absolute; - top: 0; - right: 0; - margin: 0; - padding: 0; - font-size: 20px; - cursor: pointer; - opacity: 0; - filter: alpha(opacity=0); -} diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-upload/csv-upload-template.component.html b/projects/wave-core/src/lib/operators/dialogs/csv/csv-upload/csv-upload-template.component.html deleted file mode 100644 index de7984e3..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-upload/csv-upload-template.component.html +++ /dev/null @@ -1,19 +0,0 @@ -
    - -
    -
    -

    - File too large!
    - We only accept files to a maximum size of 100MB. -

    - -
    -
    -

    - {{ this.data.file.name }} -

    - {{ data.progress }}% -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/csv-upload/csv-upload.component.ts b/projects/wave-core/src/lib/operators/dialogs/csv/csv-upload/csv-upload.component.ts deleted file mode 100644 index b478148e..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/csv-upload/csv-upload.component.ts +++ /dev/null @@ -1,116 +0,0 @@ -import {map, mapTo, filter} from 'rxjs/operators'; -import {Observable, BehaviorSubject, Subscription} from 'rxjs'; - -import {Component, Input, Output, EventEmitter, OnDestroy, OnInit} from '@angular/core'; - -enum FormStatus { - Selection, - Error, - Loading, - Finished, -} - -export interface UploadData { - file: File; - content: string; - progress: number; - isNull: boolean; -} - -@Component({ - selector: 'wave-csv-upload', - templateUrl: './csv-upload-template.component.html', - styleUrls: ['./csv-upload-style.component.css'], -}) -export class CsvUploadComponent implements OnInit, OnDestroy { - status$: BehaviorSubject = new BehaviorSubject(FormStatus.Selection); - isSelecting$: Observable; - isLoading$: Observable; - isFinished$: Observable; - isError$: Observable; - - @Input() file_size_limit: number; - @Output() onData = new EventEmitter(); - - data: UploadData = { - file: null, - content: '', - progress: 0, - isNull: true, - }; - - private subscriptions: Array = []; - - constructor() { - this.isSelecting$ = this.status$.pipe(map((status) => status === FormStatus.Selection)); - this.isLoading$ = this.status$.pipe(map((status) => status === FormStatus.Loading)); - this.isFinished$ = this.status$.pipe( - filter((status) => status === FormStatus.Finished), - mapTo(true), - ); - this.isError$ = this.status$.pipe(map((status) => status === FormStatus.Error)); - } - - ngOnInit() { - this.subscriptions.push(this.isFinished$.subscribe(() => this.onData.emit(this.data))); - } - - ngOnDestroy() { - this.subscriptions.forEach((subscription) => subscription.unsubscribe()); - } - - changeListener($event): void { - if ($event.target.files.length > 0 && $event.target.files[0].size <= this.file_size_limit) { - this.data = { - file: $event.target.files[0], - content: '', - progress: 0, - isNull: false, - }; - $event.target.value = ''; - this.upload(); - this.status$.next(FormStatus.Loading); - } else { - this.data = { - file: null, - content: '', - progress: 0, - isNull: true, - }; - if ($event.target.files[0].size > this.file_size_limit) { - $event.target.value = ''; - this.status$.next(FormStatus.Error); - } - } - } - - upload() { - let reader: FileReader = new FileReader(); - - reader.onload = (e) => { - this.data.content = reader.result as string; // FIXME: update to angular 7 -> added "as string" - this.data.progress = 100; - this.status$.next(FormStatus.Finished); - }; - - reader.readAsText(this.data.file); - } - - unerror() { - this.status$.next(FormStatus.Selection); - } - - /**This method generates a number array containing all integers i with n <= i < m - * - * @param n lowest integer. !Warning: This integer is still contained in array. - * @param m highest integer. !Warning: This integer is not contained in array. - * @returns {number[]} Array {n,..,m-1} - */ - range(n: number, m: number): number[] { - let res: number[] = []; - for (let i: number = n; i < m; i++) { - res.push(i); - } - return res; - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/csv/interval.enum.ts b/projects/wave-core/src/lib/operators/dialogs/csv/interval.enum.ts deleted file mode 100644 index f1bfefc2..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/csv/interval.enum.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Created by jmaerte on 07.04.2017. - */ -export enum IntervalFormat { - StartInf, - StartEnd, - StartDur, - StartConst, -} diff --git a/projects/wave-core/src/lib/operators/dialogs/data-repository/data-repository.component.html b/projects/wave-core/src/lib/operators/dialogs/data-repository/data-repository.component.html deleted file mode 100644 index 4395bc34..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/data-repository/data-repository.component.html +++ /dev/null @@ -1,46 +0,0 @@ -Data Repository - - - - - - - - - - - - - -
    -

    There are no sources available.

    - -
    - -
    -

    There are no sources available.

    -
    -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/data-repository/data-repository.component.scss b/projects/wave-core/src/lib/operators/dialogs/data-repository/data-repository.component.scss deleted file mode 100644 index 1eddcd94..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/data-repository/data-repository.component.scss +++ /dev/null @@ -1,34 +0,0 @@ -.datagroup { - color: var(--wave-primary-color, black) !important; -} - -.datagroup a { - color: var(--wave-primary-color, black) !important; -} - -.item { - width: 100%; - cursor: pointer; -} - -.highlight, -mat-list-item ::ng-deep .highlight { - color: var(--wave-accent-color, grey); - text-decoration: underline; -} - -mat-list-item ::ng-deep .mat-list-item-content { - height: auto !important; -} - -img { - padding: 5px 5px 5px 0; -} - -.secondary_action { - float: right; -} - -.error { - text-align: center; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/data-repository/data-repository.component.ts b/projects/wave-core/src/lib/operators/dialogs/data-repository/data-repository.component.ts deleted file mode 100644 index 88af0412..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/data-repository/data-repository.component.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {Component, ChangeDetectionStrategy} from '@angular/core'; - -import {Observable} from 'rxjs'; - -import {MappingSource} from './mapping-source.model'; -import {UserService} from '../../../users/user.service'; - -@Component({ - selector: 'wave-data-repository', - templateUrl: './data-repository.component.html', - styleUrls: ['./data-repository.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class DataRepositoryComponent { - searchTerm: string = ''; - sources: Observable>; - - constructor(public userService: UserService) { - this.sources = this.userService.getRasterSourcesStream(); - } - - reload() { - this.userService.reloadRasterSources(); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/data-repository/mapping-source.model.ts b/projects/wave-core/src/lib/operators/dialogs/data-repository/mapping-source.model.ts deleted file mode 100644 index 8ae1409f..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/data-repository/mapping-source.model.ts +++ /dev/null @@ -1,191 +0,0 @@ -import {Unit, UnitMappingDict} from '../../unit.model'; -import {MappingRasterColorizerDict} from '../../../colors/colorizer-data.model'; -import {IColorizerData} from '../../../colors/colorizer-data.model'; -import {Time, TimePoint} from '../../../time/time.model'; - -/** - * An interface for transformation of raster layer values. - */ -export interface MappingTransform { - datatype: string; - offset: number; - scale: number; - unit: Unit; -} - -/** - * An interface for the provenance data provided by MAPPING. - */ -export interface ProvenanceInfo { - uri: string; - license: string; - citation: string; -} - -/** - * An interface for raster layers provided by MAPPING. - */ -export interface SourceRasterLayerDescription { - name: string; - id: number; - datatype: string; - nodata: number; - unit: Unit; - methodology?: MappingRasterMethodology; - colorizer?: IColorizerData; - transform: MappingTransform; - hasTransform: boolean; - isSwitchable: boolean; - missingUnit?: boolean; - coords: { - crs: string; - origin: number[]; - scale: number[]; - size: number[]; - }; - provenance: ProvenanceInfo; - time_start?: TimePoint; - time_end?: TimePoint; -} - -/** - * An interface for vector layers provided by MAPPING. - */ -export interface SourceVectorLayerDescription { - name: string; - id: number | string; - title: string; - geometryType: string; // FIXME: this must be the layer type -> POINT, POLYGON, LINE... - textual: string[]; - numeric: string[]; - coords: { - crs: string; - }; - colorizer?: IColorizerData; - provenance: ProvenanceInfo; - time_start?: TimePoint; - time_end?: TimePoint; -} - -/** - * An interface for a MAPPING source and the provided data. - */ -export interface MappingSource { - operator: string; - source: string; - name: string; - rasterLayer?: SourceRasterLayerDescription[]; - vectorLayer?: SourceVectorLayerDescription[]; - descriptionText?: string; - imgUrl?: string; - tags?: Array; - provenance: ProvenanceInfo; - time_start?: TimePoint; - time_end?: TimePoint; -} - -/** - * An interface for sources as provided by MAPPING. - */ -export interface MappingSourceDict { - operator?: string; - name?: string; - dataset_name?: string; - descriptionText?: string; - imgUrl?: string; - tags?: string[]; - colorizer?: MappingRasterColorizerDict; - provenance?: { - uri: string; - license: string; - citation: string; - }; - coords: { - crs: string; - epsg?: number; - origin?: number[]; - scale?: number[]; - size?: number[]; - }; - channels?: [MappingSourceRasterLayerDict]; - layer?: [MappingSourceVectorLayerDict]; - time_start?: string; - time_end?: string; -} - -/** - * An interface for raster sources as provided by MAPPING. - */ -export interface MappingSourceRasterLayerDict { - datatype: string; - nodata: number; - name?: string; - unit?: UnitMappingDict; - methodology?: MappingRasterMethodology; - colorizer?: MappingRasterColorizerDict; - transform?: { - unit?: UnitMappingDict; - datatype: string; - scale: number; - offset: number; - }; - coords: { - crs: string; - origin: number[]; - scale: number[]; - size: number[]; - }; - provenance?: { - uri: string; - license: string; - citation: string; - }; - time_start?: string; - time_end?: string; -} - -/** - * An interface for vector sources as provided by MAPPING. - */ -export interface MappingSourceVectorLayerDict { - id?: number | string; - name: string; - title?: string; - geometry_type: string; // FIXME: this must be the layer type -> POINT, POLYGON, LINE... - textual?: string[]; - numeric?: string[]; - coords: { - crs: string; - }; - uri?: string; - license?: string; - citation?: string; - provenance?: { - uri: string; - license: string; - citation: string; - }; - time_start?: string; - time_end?: string; -} - -/** - * An interface for MAPPING responses when requesting sources. - */ -export interface MappingSourceResponse { - sourcelist: {[index: string]: MappingSourceDict}; -} - -/** - * An interface for raster methodology description. - */ -export interface MappingRasterMethodology { - type: 'SATELLITE_SENSOR'; -} - -/** - * An interface providing information for satellite sensor data. - */ -export interface MappingSatelliteSensorRasterMethodology extends MappingRasterMethodology { - central_wave_length_nm: number; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/data-repository/raster/source-dataset.component.html b/projects/wave-core/src/lib/operators/dialogs/data-repository/raster/source-dataset.component.html deleted file mode 100644 index c9a0fd75..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/data-repository/raster/source-dataset.component.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - no preview image available - - -

    {{ dataset?.descriptionText }}

    -
    - - - {{ tag }} - - - - -

    Time validity: {{ dataset?.time_start }} - {{ dataset?.time_end }}

    -
    - - open_in_new -

    - {{ dataset?.provenance?.uri }} -

    -
    -
    - - - - - Channel - - - - - - - Measurement - - {{ valid_unit(channel) }} - - - - - Start - - {{ channel.time_start }} - - - - - End - - {{ channel.time_end }} - - - - - - - -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/data-repository/raster/source-dataset.component.scss b/projects/wave-core/src/lib/operators/dialogs/data-repository/raster/source-dataset.component.scss deleted file mode 100644 index efbb79d6..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/data-repository/raster/source-dataset.component.scss +++ /dev/null @@ -1,51 +0,0 @@ -@import '~@angular/material/theming'; - -$mat-button-focus-transition: opacity 200ms $swift-ease-in-out-timing-function, background-color 200ms $swift-ease-in-out-timing-function !default; - -.dataset-name { - color: var(--wave-primary-color, black) !important; -} - -.dataset-uri { - overflow: hidden; - text-overflow: ellipsis; -} - -.secondary_action { - float: right; -} - -mat-list-item { - font-size: 12px; -} - -.mat-row { - color: var(--wave-primary-color, black) !important; - cursor: pointer; - min-height: 40px !important; -} - -.mat-cell { - font-size: 12px; -} -:host ::ng-deep .highlight { - color: var(--wave-accent-color, grey); -} - -// Element that overlays the button to show focus and hover effects. -.mat-row:hover { - // The button spec calls for focus on raised buttons (and FABs) to be indicated with a - // black, 12% opacity shade over the normal color (for both light and dark themes). - background-color: rgba(black, 0.12); - border-radius: inherit; - opacity: 1; - - transition: $mat-button-focus-transition; - - @include cdk-high-contrast { - // Note that IE will render this in the same way, no - // matter whether the theme is light or dark. This helps - // with the readability of focused buttons. - background-color: rgba(white, 0.5); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/data-repository/raster/source-dataset.component.ts b/projects/wave-core/src/lib/operators/dialogs/data-repository/raster/source-dataset.component.ts deleted file mode 100644 index 731b1aff..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/data-repository/raster/source-dataset.component.ts +++ /dev/null @@ -1,300 +0,0 @@ -import {Observable, of as observableOf} from 'rxjs'; -import {ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'; -import {MappingSource, SourceRasterLayerDescription, MappingTransform} from '../mapping-source.model'; -import {Unit} from '../../../unit.model'; -import {RasterSourceType} from '../../../types/raster-source-type.model'; -import {ResultTypes} from '../../../result-type.model'; -import {Projection, Projections} from '../../../projection.model'; -import {DataType, DataTypes} from '../../../datatype.model'; -import {RasterLayer} from '../../../../layers/layer.model'; -import {MappingRasterSymbology} from '../../../../layers/symbology/symbology.model'; -import {Operator} from '../../../operator.model'; -import {ProjectService} from '../../../../project/project.service'; -import {DataSource} from '@angular/cdk/table'; -import {GdalSourceType} from '../../../types/gdal-source-type.model'; -import {ExpressionType} from '../../../types/expression-type.model'; -import {ColorBreakpointDict} from '../../../../colors/color-breakpoint.model'; -import {ColorizerData, IColorizerData} from '../../../../colors/colorizer-data.model'; -import {GdalSourceParameterOptions} from '../../../parameter-options/gdal-source-parameter-options.model'; -import {ParameterOptionType} from '../../../operator-type-parameter-options.model'; -import {Colormap} from '../../../../colors/colormaps/colormap.model'; - -@Component({ - selector: 'wave-source-dataset', - templateUrl: './source-dataset.component.html', - styleUrls: ['./source-dataset.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class SourceDatasetComponent implements OnInit, OnChanges { - @Input() dataset: MappingSource; - @Input() searchTerm: string; - _useRawData = false; - _showPreview = false; - _showDescription = false; - _channelSource: ChannelDataSource; - _displayedColumns = ['name', 'measurement']; - - /** - * Transform the values of a colorizer to match the transformation of the raster transformation. - */ - static createAndTransformColorizer(colorizerConfig: IColorizerData, transform: MappingTransform): IColorizerData { - if (transform) { - const transformedColorizerConfig: IColorizerData = { - type: colorizerConfig.type, - breakpoints: colorizerConfig.breakpoints.map((bp: ColorBreakpointDict) => { - return { - value: ((bp.value as number) - transform.offset) * transform.scale, - rgba: bp.rgba, - }; - }), - }; - return transformedColorizerConfig; - } else { - return colorizerConfig; - } - } - - constructor(private projectService: ProjectService) {} - - ngOnInit(): void { - this._channelSource = new ChannelDataSource(this.dataset.rasterLayer); - } - ngOnChanges(changes: SimpleChanges) { - for (const key in changes) { - if (changes.hasOwnProperty(key)) { - switch (key) { - // check if there is any time-validity start/end data. If there is start/end data show the column of this data. - case 'dataset': { - this.dataset.rasterLayer.forEach((element) => { - if (element.time_start && this.dataset.time_start && !this.dataset.time_start.isSame(element.time_start)) { - if (!this._displayedColumns.includes('start')) { - this._displayedColumns.push('start'); - } - } - if (element.time_end && this.dataset.time_end && !this.dataset.time_end.isSame(element.time_end)) { - if (!this._displayedColumns.includes('end')) { - this._displayedColumns.push('end'); - } - } - // get start and end in the right order - if (this._displayedColumns[2] === 'end' && this._displayedColumns[3] === 'start') { - this._displayedColumns[2] = 'start'; - this._displayedColumns[3] = 'end'; - } - }); - } - } - } - } - } - valid_colorizer(channel: SourceRasterLayerDescription): IColorizerData { - if (channel.colorizer) { - return channel.colorizer; - } else { - return ColorizerData.grayScaleColorizer(this.valid_unit(channel)); - } - } - - valid_unit(channel: SourceRasterLayerDescription): Unit { - if (channel.hasTransform && !this.useRawData) { - return channel.transform.unit; - } else { - return channel.unit; - } - } - - simple_add(channel: SourceRasterLayerDescription) { - this.add(channel, channel.hasTransform && !this.useRawData); - } - - add(channel: SourceRasterLayerDescription, doTransform: boolean) { - const unit: Unit = channel.unit; - const mappingTransformation = channel.transform; - - let operator; - if (this.dataset.operator === GdalSourceType.TYPE) { - operator = this.createGdalSourceOperator(channel, doTransform); - } else { - operator = this.createMappingRasterDbSourceOperator(channel, doTransform); - } - - // if there is no colorizer data defined for the channel, create a 'viridis' coloring with min, max bounds - let colorizerConfig = - channel.colorizer && ColorizerData.is_valid(channel.colorizer) - ? channel.colorizer - : Colormap.createColorizerDataWithName('VIRIDIS', unit.min, unit.max); - - // if the dataset / channel has a transform specification, the colorizer defined for the raw data also requires transformation - if (doTransform) { - colorizerConfig = SourceDatasetComponent.createAndTransformColorizer(colorizerConfig, mappingTransformation); - } - - const layer = new RasterLayer({ - name: channel.name, - operator, - symbology: MappingRasterSymbology.createSymbology({ - unit: doTransform ? channel.transform.unit : unit, - colorizer: colorizerConfig, - }), - }); - this.projectService.addLayer(layer); - } - - @Input('useRawData') - set useRawData(useRawData: boolean) { - this._useRawData = useRawData; - } - - get useRawData(): boolean { - return this._useRawData; - } - - get channels(): Array { - return this.dataset.rasterLayer; - } - - get channelDataSource(): ChannelDataSource { - return this._channelSource; - } - - get displayedColumns(): Array { - return this._displayedColumns; - } - - isSingleLayerDataset(): boolean { - return this.dataset.rasterLayer.length <= 1; - } - - toggleImages() { - this._showPreview = !this._showPreview; - } - - toggleDescriptions() { - this._showDescription = !this._showDescription; - } - - toggleTransform() { - this._useRawData = !this._useRawData; - } - - /** - * Creates a gdal_source operator and a wrapping expression operator to transform values if needed. - */ - createGdalSourceOperator(channel: SourceRasterLayerDescription, doTransform: boolean): Operator { - const sourceDataType = channel.datatype; - const sourceUnit: Unit = channel.unit; - let sourceProjection: Projection; - if (channel.coords.crs) { - sourceProjection = Projections.fromCode(channel.coords.crs); - } else { - throw new Error('No projection or EPSG code defined in [' + this.dataset.name + ']. channel.id: ' + channel.id); - } - - const operatorType = new GdalSourceType({ - channelConfig: { - channelNumber: channel.id, - displayValue: channel.name, - methodology: channel.methodology, - }, - sourcename: this.dataset.source, - transform: doTransform, // TODO: user selectable transform? - }); - - const operatorParameterOptions = new GdalSourceParameterOptions({ - operatorType: operatorType.toString(), - channelConfig: { - kind: ParameterOptionType.DICT_ARRAY, - options: this.channels.map((c, i) => { - return { - channelNumber: i, - displayValue: c.name, - methodology: c.methodology, - }; - }), - }, - }); - - const sourceOperator = new Operator({ - operatorType, - operatorTypeParameterOptions: operatorParameterOptions, - resultType: ResultTypes.RASTER, - projection: sourceProjection, - attributes: ['value'], - dataTypes: new Map().set('value', DataTypes.fromCode(sourceDataType)), - units: new Map().set('value', sourceUnit), - }); - - if (doTransform && channel.hasTransform) { - const transformUnit = channel.transform.unit; - const transformDatatype = DataTypes.fromCode(channel.transform.datatype); - - const transformOperatorType = new ExpressionType({ - unit: transformUnit, - expression: '(A -' + channel.transform.offset.toString() + ') *' + channel.transform.scale.toString(), - datatype: transformDatatype, - }); - - const transformOperator = new Operator({ - operatorType: transformOperatorType, - resultType: ResultTypes.RASTER, - projection: sourceProjection, - attributes: ['value'], - dataTypes: new Map().set('value', transformDatatype), - units: new Map().set('value', transformUnit), - rasterSources: [sourceOperator], - }); - return transformOperator; - } - - return sourceOperator; - } - - createMappingRasterDbSourceOperator(channel: SourceRasterLayerDescription, doTransform: boolean) { - let dataType = channel.datatype; - let unit: Unit = channel.unit; - - if (doTransform && channel.hasTransform) { - unit = channel.transform.unit; - dataType = channel.transform.datatype; - } - - let sourceProjection: Projection; - if (channel.coords.crs) { - sourceProjection = Projections.fromCode(channel.coords.crs); - } else { - throw new Error('No projection or EPSG code defined in [' + this.dataset.name + ']. channel.id: ' + channel.id); - } - - const operatorType = new RasterSourceType({ - channel: channel.id, - sourcename: this.dataset.source, - transform: doTransform, // TODO: user selectable transform? - }); - - const operator = new Operator({ - operatorType, - resultType: ResultTypes.RASTER, - projection: sourceProjection, - attributes: ['value'], - dataTypes: new Map().set('value', DataTypes.fromCode(dataType)), - units: new Map().set('value', unit), - }); - - return operator; - } -} - -class ChannelDataSource extends DataSource { - private channels: Array; - - constructor(channels: Array) { - super(); - this.channels = channels; - } - - connect(): Observable> { - return observableOf(this.channels); - } - - disconnect() {} -} diff --git a/projects/wave-core/src/lib/operators/dialogs/data-repository/vector/vector-source-dataset.component.html b/projects/wave-core/src/lib/operators/dialogs/data-repository/vector/vector-source-dataset.component.html deleted file mode 100644 index cfffffd0..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/data-repository/vector/vector-source-dataset.component.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - no preview image available - - -

    {{ dataset?.descriptionText }}

    -
    - - - -

    Time validity: {{ dataset?.time_start }} - {{ dataset?.time_end }}

    -
    - - open_in_new -

    - {{ dataset?.provenance?.uri }} -

    -
    -
    - - - - - Title - - {{ layer.title }} - - - - - Start - - {{ layer.time_start }} - - - - - End - - {{ layer.time_end }} - - - - - - - -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/data-repository/vector/vector-source-dataset.component.scss b/projects/wave-core/src/lib/operators/dialogs/data-repository/vector/vector-source-dataset.component.scss deleted file mode 100644 index 191bd17e..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/data-repository/vector/vector-source-dataset.component.scss +++ /dev/null @@ -1,48 +0,0 @@ -@import '~@angular/material/theming'; - -$mat-button-focus-transition: opacity 200ms $swift-ease-in-out-timing-function, background-color 200ms $swift-ease-in-out-timing-function !default; - -.dataset-name { - color: var(--wave-primary-color, black) !important; -} - -.dataset-uri { - overflow: hidden; - text-overflow: ellipsis; -} - -.secondary_action { - float: right; -} - -mat-list-item { - font-size: 12px; -} - -.mat-row { - color: var(--wave-primary-color, black) !important; - cursor: pointer; - min-height: 40px !important; -} - -.mat-cell { - font-size: 12px; -} - -// Element that overlays the button to show focus and hover effects. -.mat-row:hover { - // The button spec calls for focus on raised buttons (and FABs) to be indicated with a - // black, 12% opacity shade over the normal color (for both light and dark themes). - background-color: rgba(black, 0.12); - border-radius: inherit; - opacity: 1; - - transition: $mat-button-focus-transition; - - @include cdk-high-contrast { - // Note that IE will render this in the same way, no - // matter whether the theme is light or dark. This helps - // with the readability of focused buttons. - background-color: rgba(white, 0.5); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/data-repository/vector/vector-source-dataset.component.ts b/projects/wave-core/src/lib/operators/dialogs/data-repository/vector/vector-source-dataset.component.ts deleted file mode 100644 index acf4ec2d..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/data-repository/vector/vector-source-dataset.component.ts +++ /dev/null @@ -1,200 +0,0 @@ -import {of as observableOf, Observable} from 'rxjs'; -import {ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'; -import {MappingSource, SourceVectorLayerDescription} from '../mapping-source.model'; -import {Projection, Projections} from '../../../projection.model'; -import {DataType, DataTypes} from '../../../datatype.model'; -import {VectorLayer} from '../../../../layers/layer.model'; -import {PointSymbology, VectorSymbology, LineSymbology} from '../../../../layers/symbology/symbology.model'; -import {Operator} from '../../../operator.model'; -import {ProjectService} from '../../../../project/project.service'; -import {DataSource} from '@angular/cdk/table'; - -import {RandomColorService} from '../../../../util/services/random-color.service'; -import {OgrSourceType} from '../../../types/ogr-source-type.model'; -import {ResultTypes} from '../../../result-type.model'; -import {WHITE} from '../../../../colors/color'; -import {NotificationService} from '../../../../notification.service'; - -@Component({ - selector: 'wave-vector-source-dataset', - templateUrl: './vector-source-dataset.component.html', - styleUrls: ['./vector-source-dataset.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class VectorSourceDatasetComponent implements OnInit, OnChanges { - @Input() dataset: MappingSource; - @Input() searchTerm: string; - _useRawData = false; - _showPreview = false; - _showDescription = false; - _tableSource: LayerTableDataSource; - _displayedColumns = ['title']; - - constructor( - private projectService: ProjectService, - private randomColorService: RandomColorService, - private notificationService: NotificationService, - ) {} - - ngOnInit(): void { - this._tableSource = new LayerTableDataSource(this.dataset.vectorLayer); - } - - add(layer: SourceVectorLayerDescription) { - let operator; - if (this.dataset.operator === OgrSourceType.TYPE) { - operator = this.createOgrSourceOperator(layer); - } else { - throw new Error('Unsupported operator: ' + this.dataset.operator); - } - - let clustered = false; - let symbology; - switch (operator.resultType) { - case ResultTypes.POINTS: { - symbology = PointSymbology.createClusterSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - fillColorizer: layer.colorizer, - }); - clustered = true; - break; - } - case ResultTypes.POLYGONS: { - symbology = VectorSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - fillColorizer: layer.colorizer, - }); - break; - } - case ResultTypes.LINES: { - symbology = LineSymbology.createSymbology({ - fillRGBA: WHITE, - strokeRGBA: this.randomColorService.getRandomColorRgba(), - strokeWidth: 2, - }); - break; - } - default: { - throw new Error('unhandled result type: ' + operator.resultType.name); - } - } - - const l = new VectorLayer({ - name: layer.name, - operator, - symbology, - clustered, - }); - this.projectService.addLayer(l); - } - ngOnChanges(changes: SimpleChanges) { - for (const key in changes) { - if (changes.hasOwnProperty(key)) { - switch (key) { - // check if there is any time-validity start/end data. If there is start/end data show the column of this data. - case 'dataset': { - this.dataset.rasterLayer.forEach((element) => { - if (element.time_start && this.dataset.time_start && !this.dataset.time_start.isSame(element.time_start)) { - if (!this._displayedColumns.includes('start')) { - this._displayedColumns.push('start'); - } - } - if (element.time_end && this.dataset.time_end && !this.dataset.time_end.isSame(element.time_end)) { - if (!this._displayedColumns.includes('end')) { - this._displayedColumns.push('end'); - } - } - // get start and end in the right order - if (this._displayedColumns[2] === 'end' && this._displayedColumns[3] === 'start') { - this._displayedColumns[2] = 'start'; - this._displayedColumns[3] = 'end'; - } - }); - } - } - } - } - } - - get layers(): Array { - return this.dataset.vectorLayer; - } - - get layerTableDataSource(): LayerTableDataSource { - return this._tableSource; - } - - get displayedColumns(): Array { - return this._displayedColumns; - } - - isSingleLayerDataset(): boolean { - return this.dataset.rasterLayer.length <= 1; - } - - toggleImages() { - this._showPreview = !this._showPreview; - } - - toggleDescriptions() { - this._showDescription = !this._showDescription; - } - - /** - * Creates a gdal_source operator and a wrapping expression operator to transform values if needed. - */ - createOgrSourceOperator(layer: SourceVectorLayerDescription): Operator { - if (!layer.geometryType) { - this.notificationService.error( - 'No geometry type defined in [' + this.dataset.name + '] assuming "POINTS". (channel.id: ' + layer.id + ')', - ); - layer.geometryType = 'POINTS'; - } - - const sourceDataType = ResultTypes.fromCode(layer.geometryType); - - if (!layer.coords || !layer.coords.crs) { - this.notificationService.error( - 'No projection or EPSG code defined in [' + this.dataset.name + '] assuming EPSG:4326. (channel.id: ' + layer.id + ')', - ); - layer.coords = {crs: 'EPSG:4326'}; - } - - const sourceProjection = Projections.fromCode(layer.coords.crs); - const dataTypes = new Map(); - layer.numeric.forEach((x) => dataTypes.set(x, DataTypes.Float32)); - layer.textual.forEach((x) => dataTypes.set(x, DataTypes.Alphanumeric)); - - const operatorType = new OgrSourceType({ - dataset_id: this.dataset.name, - layer_id: layer.id, - textual: layer.textual, - numeric: layer.numeric, - }); - - const sourceOperator = new Operator({ - operatorType, - resultType: sourceDataType, - projection: sourceProjection, - attributes: [].concat(layer.numeric, layer.textual), - dataTypes, - }); - - return sourceOperator; - } -} - -class LayerTableDataSource extends DataSource { - private layers: Array; - - constructor(layers: Array) { - super(); - this.layers = layers; - } - - connect(): Observable> { - return observableOf(this.layers); - } - - disconnect() {} -} diff --git a/projects/wave-core/src/lib/operators/dialogs/draw-features/ol-draw-features.component.html b/projects/wave-core/src/lib/operators/dialogs/draw-features/ol-draw-features.component.html deleted file mode 100644 index 0c15700f..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/draw-features/ol-draw-features.component.html +++ /dev/null @@ -1,29 +0,0 @@ -Draw Features - - -

    - This is a tool for drawing new features by clicking on the map. Select the Feature type you want to draw (points, lines or - polygons) and click Start. Click the End button if you are finished or Cancel if you want to start all over. - The new layer appears in the layer list on the left. -

    -

    Note: In the layer's context menu you can change the layer name, edit the symbology and more.

    -
    - - - - {{ featureType }} - - - -
    - - - - - -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/draw-features/ol-draw-features.component.scss b/projects/wave-core/src/lib/operators/dialogs/draw-features/ol-draw-features.component.scss deleted file mode 100644 index f611aa27..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/draw-features/ol-draw-features.component.scss +++ /dev/null @@ -1,8 +0,0 @@ -:host { - display: block; - padding: 1rem; -} - -mat-form-field { - width: 100%; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/draw-features/ol-draw-features.component.ts b/projects/wave-core/src/lib/operators/dialogs/draw-features/ol-draw-features.component.ts deleted file mode 100644 index f4586c30..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/draw-features/ol-draw-features.component.ts +++ /dev/null @@ -1,170 +0,0 @@ -import {ChangeDetectionStrategy, Component, OnDestroy} from '@angular/core'; -import {MapService} from '../../../map/map.service'; -import OlFormatGeoJson from 'ol/format/GeoJSON'; -import {Vector as OlVectorSource} from 'ol/source'; -import OlGeometryType from 'ol/geom/GeometryType'; -import {Projections, Projection} from '../../projection.model'; -import {Operator} from '../../operator.model'; -import {AbstractVectorSymbology, LineSymbology, PointSymbology, VectorSymbology} from '../../../layers/symbology/symbology.model'; -import {UnexpectedResultType} from '../../../util/errors'; -import {VectorLayer} from '../../../layers/layer.model'; -import {ResultType, ResultTypes} from '../../result-type.model'; -import {ProjectService} from '../../../project/project.service'; -import {RandomColorService} from '../../../util/services/random-color.service'; -import {NotificationService} from '../../../notification.service'; -import {Subscription} from 'rxjs'; -import {OgrRawSourceType} from '../../types/ogr-raw-source-type.model'; -import {DataTypes} from '../../datatype.model'; -import {Map as ImmutableMap} from 'immutable'; -import {Unit} from '../../unit.model'; - -/** - * The feature draw component. Together with the MapService it allows to add new fueatures by drawing them on the map. - */ -@Component({ - selector: 'wave-ol-draw-features', - templateUrl: './ol-draw-features.component.html', - styleUrls: ['./ol-draw-features.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class OlDrawFeaturesComponent implements OnDestroy { - // the list of supported feature types - featureTypes = [ResultTypes.POLYGONS, ResultTypes.POINTS, ResultTypes.LINES]; - // the current feature type - selectedFeatureType: ResultType; - // the corresponding open layers geometry type - olGeometryType: OlGeometryType; - - isDrawingActive = false; - // the open layers feature writer - we use GeoJson - olFeatureWriter = new OlFormatGeoJson(); - - featureLayerName = 'new feature layer'; - - // the projection of the map - mapProjection: Projection; - // a subscription providing the map projection and updates if it changes - mapProjectionSubscription: Subscription; - - constructor( - private mapService: MapService, - private projectService: ProjectService, - private randomColorService: RandomColorService, - private notificationService: NotificationService, - ) { - this.mapProjectionSubscription = projectService.getProjectionStream().subscribe((p) => (this.mapProjection = p)); - } - - ngOnDestroy(): void { - if (this.isDrawingActive) { - this.cancelDrawing(); - } - this.mapProjectionSubscription.unsubscribe(); - } - - updateFeatureType(resultType: ResultType) { - this.selectedFeatureType = resultType; - - switch (resultType) { - case ResultTypes.POINTS: - this.olGeometryType = OlGeometryType.POINT; - break; - case ResultTypes.POLYGONS: - this.olGeometryType = OlGeometryType.POLYGON; - break; - case ResultTypes.LINES: - this.olGeometryType = OlGeometryType.LINE_STRING; - break; - default: - throw new UnexpectedResultType(); - } - } - - startDrawing() { - this.isDrawingActive = true; - this.mapService.startDrawInteraction(this.olGeometryType); - this.notificationService.info('Start drawing…'); - } - - cancelDrawing() { - this.isDrawingActive = false; - this.mapService.endDrawInteraction(); - this.notificationService.info('Draw features canceled.'); - } - - endDrawing() { - this.isDrawingActive = false; - const olSource = this.mapService.endDrawInteraction(); - if (olSource.getFeatures().length > 0) { - this.createAndAddOperatorFromSource(olSource); - } else { - this.notificationService.info('Empty layer skipped.'); - } - } - - private createAndAddOperatorFromSource(olSource: OlVectorSource) { - let resultSymbology: AbstractVectorSymbology; - - switch (this.selectedFeatureType) { - case ResultTypes.POINTS: - resultSymbology = PointSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - break; - case ResultTypes.POLYGONS: - resultSymbology = VectorSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - break; - case ResultTypes.LINES: - resultSymbology = LineSymbology.createSymbology({ - strokeRGBA: this.randomColorService.getRandomColorRgba(), - }); - break; - default: - throw new UnexpectedResultType(); - } - - resultSymbology.textAttribute = 'id'; - - const geoJson = this.olFeatureWriter.writeFeaturesObject(olSource.getFeatures(), { - featureProjection: this.mapProjection.getCode(), - dataProjection: Projections.WGS_84.getCode(), - }); - - // add `id` attribute to each feature - for (let i = 0; i < geoJson.features.length; ++i) { - geoJson.features[i].properties = {id: i + 1}; - } - - const dataUrl = `data:text/json,${encodeURIComponent(JSON.stringify(geoJson))}`; - - const sourceType = new OgrRawSourceType({ - filename: dataUrl, - time: 'none', - columns: { - numeric: ['id'], - textual: [], - }, - on_error: 'abort', - }); - - const operator = new Operator({ - operatorType: sourceType, - resultType: this.selectedFeatureType, - projection: Projections.WGS_84, - attributes: ['id'], - dataTypes: ImmutableMap({id: DataTypes.UInt32}), - units: ImmutableMap({id: Unit.defaultUnit}), - }); - - const layer = new VectorLayer({ - name: this.featureLayerName, - operator, - symbology: resultSymbology, - clustered: false, - }); - - this.projectService.addLayer(layer); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/expression-operator/expression-operator.component.html b/projects/wave-core/src/lib/operators/dialogs/expression-operator/expression-operator.component.html deleted file mode 100644 index 16992ef5..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/expression-operator/expression-operator.component.html +++ /dev/null @@ -1,84 +0,0 @@ -Calculate Expression on Raster - - -

    The Expression Operator allows applying mathematical calculations on one or more raster layers.

    -

    - For the expression, each raster is referred to as an alphabetic character, e.g., A for the first raster. It is possible to use basic - operations like +, -, * and /, e.g., A + B. -

    -

    - It is necessary to specify the output datatype for the expression. The list indicates the data type of the input. Furthermore, it is - required to specify the number range of the data in the form of min and max values. The system will choose an appropriate NO DATA - value automatically. -

    -

    - There is the option to specify an output unit for the expression result, e.g. temperature in °C. This will be shown in - the legend and automatically used in plots, etc. -

    -

    - Since the input rasters can be in differing projections, it is required to specify the output projection. This projection is used - when applying the operator. -

    -
    - -
    -
    - - -

    Use A to reference the existing pixel of the first raster, B for the second one, etc.

    - - Expression - - - - Output Data Type - - - {{ dataType[0] }} {{ dataType[1] }} - - - -
    - - Minimum Value - - -
    - - Maximum Value - - -
    - - Output Unit - - Unitless - {{ unit }} - Custom - - -
    - - Measurement - - - - Unit - - -
    - You must select a unit or specify one - - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/expression-operator/expression-operator.component.scss b/projects/wave-core/src/lib/operators/dialogs/expression-operator/expression-operator.component.scss deleted file mode 100644 index 9599b01e..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/expression-operator/expression-operator.component.scss +++ /dev/null @@ -1,30 +0,0 @@ -:host { - display: block; - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - .custom-unit { - margin-bottom: 1rem; - } - - > mat-error { - margin-bottom: 1rem; - } -} - -.actions { - text-align: right; - padding: 1rem; -} - -mat-form-field { - width: 100%; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/expression-operator/expression-operator.component.ts b/projects/wave-core/src/lib/operators/dialogs/expression-operator/expression-operator.component.ts deleted file mode 100644 index 44f490eb..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/expression-operator/expression-operator.component.ts +++ /dev/null @@ -1,241 +0,0 @@ -import {filter, map, tap} from 'rxjs/operators'; -import {Observable, Subscription} from 'rxjs'; - -import {AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy} from '@angular/core'; -import {FormControl, FormGroup, ValidationErrors, Validators} from '@angular/forms'; -import {ResultTypes} from '../../result-type.model'; -import {DataType, DataTypes} from '../../datatype.model'; -import {Interpolation, Unit} from '../../unit.model'; -import {LetterNumberConverter} from '../helpers/multi-layer-selection/multi-layer-selection.component'; -import {Operator} from '../../operator.model'; -import {ExpressionType} from '../../types/expression-type.model'; -import {RasterLayer} from '../../../layers/layer.model'; -import {MappingRasterSymbology} from '../../../layers/symbology/symbology.model'; -import {WaveValidators} from '../../../util/form.validators'; -import {ProjectService} from '../../../project/project.service'; - -/** - * This dialog allows calculations on (one or more) raster layers. - */ -@Component({ - selector: 'wave-expression-operator', - templateUrl: './expression-operator.component.html', - styleUrls: ['./expression-operator.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ExpressionOperatorComponent implements AfterViewInit, OnDestroy { - private static readonly RASTER_VALUE = 'value'; - readonly RASTER_TYPE = [ResultTypes.RASTER]; - readonly UNITLESS_UNIT = Unit.defaultUnit; - readonly CUSTOM_UNIT_ID = 'CUSTOM'; - - form: FormGroup; - - outputDataTypes$: Observable>; - outputUnits$: Observable>; - outputUnitIsCustom$: Observable; - - unitSubscription: Subscription; - - /** - * DI of services and setup of observables for the template - */ - constructor(private projectService: ProjectService) { - this.form = new FormGroup( - { - rasterLayers: new FormControl(undefined, [Validators.required]), - expression: new FormControl('1 * A', Validators.compose([Validators.required, Validators.pattern('.*A.*')])), - dataType: new FormControl(undefined, [Validators.required]), - minValue: new FormControl(0, Validators.compose([WaveValidators.isNumber])), - maxValue: new FormControl(0, Validators.compose([WaveValidators.isNumber])), - unit: new FormControl(undefined, [Validators.required]), - customUnit: new FormGroup({ - measurement: new FormControl(undefined, [Validators.required]), - unit: new FormControl(undefined, [Validators.required]), - }), - projection: new FormControl(undefined, [Validators.required]), - name: new FormControl('Expression', [Validators.required, WaveValidators.notOnlyWhitespace]), - }, - [unitOrCustomUnit], - ); - - this.outputUnits$ = this.form.controls.rasterLayers.valueChanges.pipe( - map((rasterLayers: Array>) => { - return rasterLayers - .map((layer) => layer.operator.getUnit(ExpressionOperatorComponent.RASTER_VALUE)) - .filter((unit) => unit !== this.UNITLESS_UNIT); - }), - tap((outputUnits) => { - const unitControl = this.form.controls['unit']; - const currentUnit: Unit = unitControl.value; - if (outputUnits.length > 0 && outputUnits.indexOf(currentUnit) === -1) { - setTimeout(() => { - unitControl.setValue(outputUnits[0]); - }); - } - - return outputUnits; - }), - ); - - this.outputUnitIsCustom$ = this.form.controls.unit.valueChanges.pipe( - map((unit) => unit === this.CUSTOM_UNIT_ID), - tap((isCustomUnit) => { - if (isCustomUnit) { - this.form.controls.customUnit.enable({onlySelf: true}); - } else { - this.form.controls.customUnit.disable({onlySelf: true}); - } - }), - ); - - this.unitSubscription = this.form.controls.unit.valueChanges - .pipe(filter((unit) => unit instanceof Unit)) - .subscribe((unit: Unit) => { - if (unit.min) { - this.form.controls.minValue.setValue(unit.min); - } - if (unit.max) { - this.form.controls.maxValue.setValue(unit.max); - } - }); - - this.outputDataTypes$ = this.form.controls.rasterLayers.valueChanges.pipe( - map((rasterLayers: Array>) => { - const outputDataTypes = DataTypes.ALL_NUMERICS.map((dataType: DataType) => [dataType, '']) as Array<[DataType, string]>; - - const rasterDataTypes = rasterLayers.map((layer) => - layer ? layer.operator.getDataType(ExpressionOperatorComponent.RASTER_VALUE) : undefined, - ); - - for (let i = 0; i < outputDataTypes.length; i++) { - const outputDataType = outputDataTypes[i][0]; - - const indices = rasterDataTypes - .map((dataType, index) => (dataType === outputDataType ? index : -1)) - .filter((index) => index >= 0) - .map((index) => LetterNumberConverter.toLetters(index + 1)); - - if (indices.length > 0) { - outputDataTypes[i][1] = `(like ${indices.length > 1 ? 'layers' : 'layer'} ${indices.join(', ')})`; - } - } - - return outputDataTypes; - }), - tap((outputDataTypes) => { - const dataTypeControl = this.form.controls.dataType; - const currentDataType: DataType = dataTypeControl.value; - - const rasterDataTypes = (this.form.controls.rasterLayers.value as Array>) - .map((layer) => (layer ? layer.operator.getDataType(ExpressionOperatorComponent.RASTER_VALUE) : undefined)) - .filter((layer) => !!layer); - - if (rasterDataTypes.includes(currentDataType)) { - // is already set at a meaningful type - return; - } - - let selectedDataType: DataType = currentDataType ? currentDataType : outputDataTypes[0][0]; // use default - if (rasterDataTypes.length) { - selectedDataType = rasterDataTypes[0]; - } - - setTimeout(() => { - dataTypeControl.setValue(selectedDataType); - }); - }), - ); - } - - ngAfterViewInit() { - setTimeout(() => - this.form.controls['rasterLayers'].updateValueAndValidity({ - onlySelf: false, - emitEvent: true, - }), - ); - } - - ngOnDestroy() { - this.unitSubscription.unsubscribe(); - } - - /** - * Uses the user input and creates a new expression operator. - * The resulting layer is added to the map. - */ - add() { - const name: string = this.form.controls['name'].value; - const dataType: DataType = this.form.controls['dataType'].value; - const expression: string = this.form.controls['expression'].value; - const rasterLayers = this.form.controls['rasterLayers'].value; - const projection = this.form.controls['projection'].value; - const minValue = this.form.controls['minValue'].value; - const maxValue = this.form.controls['maxValue'].value; - - const selectedUnit: Unit | string = this.form.controls['unit'].value; - let unit: Unit; - if (selectedUnit instanceof Unit) { - unit = new Unit({ - measurement: selectedUnit.measurement, - unit: selectedUnit.unit, - interpolation: selectedUnit.interpolation, - classes: selectedUnit.classes, - min: minValue, - max: maxValue, - }); - } else { - // custom unit from strings - unit = new Unit({ - measurement: this.form.controls.customUnit.value.measurement, - unit: this.form.controls.customUnit.value.unit, - interpolation: Interpolation.Continuous, - min: minValue, - max: maxValue, - }); - } - - const operator = new Operator({ - operatorType: new ExpressionType({ - expression, - datatype: dataType, - unit, - }), - resultType: ResultTypes.RASTER, - projection, - attributes: ['value'], - dataTypes: new Map().set('value', dataType), - units: new Map().set('value', unit), - rasterSources: rasterLayers.map((l) => l.operator.getProjectedOperator(projection)), - }); - - const layer = new RasterLayer({ - name, - operator, - symbology: MappingRasterSymbology.createSymbology({unit}), - }); - this.projectService.addLayer(layer); - } -} - -/** - * This is a validator function that checks whether a fields contains either a valid existing unit - * or a new (custom) unit. - */ -function unitOrCustomUnit(group: FormGroup): ValidationErrors | null { - const unit: Unit = group.controls.unit.value; - if (unit instanceof Unit) { - return null; - } - - const customUnit: {measurement: string; unit: string} = group.controls.customUnit.value; - - if (customUnit.measurement && customUnit.unit) { - return null; - } - - return { - unitOrCustomUnit: true, - }; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/featuredb-source-list/featuredb-source-list.component.html b/projects/wave-core/src/lib/operators/dialogs/featuredb-source-list/featuredb-source-list.component.html deleted file mode 100644 index 2b5307fa..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/featuredb-source-list/featuredb-source-list.component.html +++ /dev/null @@ -1,19 +0,0 @@ -Custom Features - - - - - - - - - - -

    -

    Add this {{ entry.operator.resultType }} data set.

    -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/featuredb-source-list/featuredb-source-list.component.scss b/projects/wave-core/src/lib/operators/dialogs/featuredb-source-list/featuredb-source-list.component.scss deleted file mode 100644 index 3ff806ed..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/featuredb-source-list/featuredb-source-list.component.scss +++ /dev/null @@ -1,15 +0,0 @@ -mat-toolbar ::ng-deep mat-toolbar-row:first-child { - display: none; -} - -mat-list-item { - cursor: pointer; -} - -p { - color: var(--wave-foreground-secondary-text-color, grey); -} - -mat-list-item ::ng-deep .highlight { - color: var(--wave-accent-color, grey); -} diff --git a/projects/wave-core/src/lib/operators/dialogs/featuredb-source-list/featuredb-source-list.component.ts b/projects/wave-core/src/lib/operators/dialogs/featuredb-source-list/featuredb-source-list.component.ts deleted file mode 100644 index 5e304dee..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/featuredb-source-list/featuredb-source-list.component.ts +++ /dev/null @@ -1,87 +0,0 @@ -import {combineLatest as observableCombineLatest, BehaviorSubject, Observable, ReplaySubject} from 'rxjs'; -import {first, map} from 'rxjs/operators'; - -import {ChangeDetectionStrategy, Component, OnInit} from '@angular/core'; -import {UserService} from '../../../users/user.service'; -import {Operator} from '../../operator.model'; -import {VectorLayer} from '../../../layers/layer.model'; -import {ResultTypes} from '../../result-type.model'; -import {AbstractVectorSymbology, PointSymbology, VectorSymbology} from '../../../layers/symbology/symbology.model'; -import {RandomColorService} from '../../../util/services/random-color.service'; -import {CsvDialogComponent} from '../csv/csv-dialog/csv-dialog.component'; -import {MatDialog} from '@angular/material/dialog'; -import {ProjectService} from '../../../project/project.service'; - -function nameComparator(a: string, b: string): number { - const stripped = (s: string): string => s.replace(' ', ''); - - return stripped(a).localeCompare(stripped(b)); -} - -@Component({ - selector: 'wave-featuredb-source-list', - templateUrl: './featuredb-source-list.component.html', - styleUrls: ['./featuredb-source-list.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class FeaturedbSourceListComponent implements OnInit { - searchString$ = new BehaviorSubject(''); - entries$ = new ReplaySubject>(1); - filteredEntries$: Observable>; - - constructor( - private userService: UserService, - private projectService: ProjectService, - private randomColorService: RandomColorService, - public dialog: MatDialog, - ) {} - - ngOnInit() { - this.refresh(); - - this.filteredEntries$ = observableCombineLatest(this.entries$, this.searchString$, (entries, searchString) => - entries.filter((entry) => entry.name.indexOf(searchString) >= 0).sort((a, b) => nameComparator(a.name, b.name)), - ); - } - - refresh() { - this.userService - .getFeatureDBList() - .pipe(map((entries) => entries.sort())) - .subscribe((entries) => this.entries$.next(entries)); - } - - openCSVDialog() { - this.dialog - .open(CsvDialogComponent) - .afterClosed() - .pipe(first()) - .subscribe(() => this.refresh()); - } - - add(entry: {name: string; operator: Operator}) { - const color = this.randomColorService.getRandomColorRgba(); - let symbology: AbstractVectorSymbology; - let clustered: boolean; - - if (entry.operator.resultType === ResultTypes.POINTS) { - symbology = PointSymbology.createClusterSymbology({ - fillRGBA: color, - }); - clustered = true; - } else { - symbology = VectorSymbology.createSymbology({ - fillRGBA: color, - }); - clustered = false; - } - - const layer = new VectorLayer({ - name: entry.name, - operator: entry.operator, - symbology, - clustered, - }); - this.projectService.addLayer(layer); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/gbif-operator/gbif-operator.component.html b/projects/wave-core/src/lib/operators/dialogs/gbif-operator/gbif-operator.component.html deleted file mode 100644 index a065eb72..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/gbif-operator/gbif-operator.component.html +++ /dev/null @@ -1,56 +0,0 @@ -GBIF Occurences Loader -
    -
    - -
    - - Search Level - - - {{ level }} - - - -
    - -
    - - - - - - {{ result }} - - -
    -
    - - -
    -
    -
    - - -
    - GBIF ({{ gbifCount }}) - IUCN ({{ iucnCount }}) -

    No Lookup Results

    -
    -
    - -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/gbif-operator/gbif-operator.component.scss b/projects/wave-core/src/lib/operators/dialogs/gbif-operator/gbif-operator.component.scss deleted file mode 100644 index 2f62bb05..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/gbif-operator/gbif-operator.component.scss +++ /dev/null @@ -1,14 +0,0 @@ -:host { - display: block; - padding: 1rem; -} - -mat-progress-spinner { - width: 25%; - height: auto; - margin: 0 auto; -} - -button:last-child { - margin-top: 2rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/gbif-operator/gbif-operator.component.ts b/projects/wave-core/src/lib/operators/dialogs/gbif-operator/gbif-operator.component.ts deleted file mode 100644 index cf2d906f..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/gbif-operator/gbif-operator.component.ts +++ /dev/null @@ -1,322 +0,0 @@ -import {BehaviorSubject, Observable, of as observableOf, Subscription} from 'rxjs'; -import {distinctUntilChanged, mergeMap, startWith, throttleTime} from 'rxjs/operators'; - -import {AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {Config} from '../../../config.service'; -import {MappingQueryService} from '../../../queries/mapping-query.service'; -import {OperatorType} from '../../operator-type.model'; -import {ResultType, ResultTypes} from '../../result-type.model'; -import {BasicColumns, GFBioSourceType} from '../../types/gfbio-source-type.model'; -import {Operator} from '../../operator.model'; -import {Projections} from '../../projection.model'; -import {AbstractVectorSymbology, PointSymbology, VectorSymbology, MappingRasterSymbology} from '../../../layers/symbology/symbology.model'; -import {RandomColorService} from '../../../util/services/random-color.service'; -import {Interpolation, Unit} from '../../unit.model'; -import {DataType, DataTypes} from '../../datatype.model'; -import {HttpClient} from '@angular/common/http'; -import {LayerService} from '../../../layers/layer.service'; -import {RasterLayer, VectorLayer} from '../../../layers/layer.model'; -import {UnexpectedResultType} from '../../../util/errors'; -import {MatAutocompleteTrigger} from '@angular/material/autocomplete'; -import {ProjectService} from '../../../project/project.service'; -import {HeatmapType} from '../../types/heatmap-type.model'; - -function oneIsTrue(group: FormGroup): {[key: string]: boolean} { - const errors: { - noneIsTrue?: boolean; - } = {}; - - let noneIsTrue = true; - for (const key in group.controls) { - if (group.controls[key].value as boolean) { - noneIsTrue = false; - break; - } - } - if (noneIsTrue) { - errors.noneIsTrue = true; - } - - return Object.keys(errors).length > 0 ? errors : null; -} - -enum Mode { - SEARCH = 1, - SELECT = 2, -} - -@Component({ - selector: 'wave-gbif-operator', - templateUrl: './gbif-operator.component.html', - styleUrls: ['./gbif-operator.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class GbifOperatorComponent implements OnInit, AfterViewInit, OnDestroy { - Mode = Mode; - - form: FormGroup; - - @ViewChild(MatAutocompleteTrigger, {static: true}) autoCompleteTrigger: MatAutocompleteTrigger; - - mode$ = new BehaviorSubject(1); - loading$ = new BehaviorSubject(false); - - minSearchLength = 4; - autoCompleteResults$: Observable>; - - gbifCount: number; - iucnCount: number; - - taxonLevels: Array = ['Species', 'Genus', 'Family']; - - private gbifColumns: BasicColumns = {numeric: [], textual: []}; - private gbifAttributes: Array = []; - private gbifUnits = new Map(); - private gbifDatatypes = new Map(); - - private iucnColumns: BasicColumns = {numeric: [], textual: []}; - private iucnAttributes: Array = []; - private iucnUnits = new Map(); - private iucnDatatypes = new Map(); - - private subscriptions: Array = []; - - constructor( - private config: Config, - private mappingQueryService: MappingQueryService, - private formBuilder: FormBuilder, - private randomColorService: RandomColorService, - private http: HttpClient, - private layerService: LayerService, - private projectService: ProjectService, - ) {} - - ngOnInit() { - this.form = this.formBuilder.group({ - name: [undefined, Validators.required], - searchTerm: [undefined, Validators.required], - searchLevel: [this.taxonLevels[0], Validators.required], - select: this.formBuilder.group( - { - gbif: [false], - iucn: [false], - }, - { - validator: oneIsTrue, - }, - ), - }); - - this.subscriptions.push( - this.mode$.subscribe((mode) => { - if (mode === Mode.SEARCH) { - this.form.controls['searchTerm'].enable(); - this.form.controls['searchLevel'].enable(); - } else { - this.form.controls['searchTerm'].disable(); - this.form.controls['searchLevel'].disable(); - } - }), - ); - - this.autoCompleteResults$ = this.form.controls['searchTerm'].valueChanges.pipe( - startWith(null), - throttleTime(this.config.DELAYS.DEBOUNCE), - distinctUntilChanged(), - mergeMap((autocompleteString: string) => { - if (autocompleteString && autocompleteString.length >= this.minSearchLength) { - return this.mappingQueryService.getGBIFAutoCompleteResults(this.form.controls['searchLevel'].value, autocompleteString); - } else { - return observableOf([]); - } - }), - ); - - // TODO: think about very unlikely race condition - this.http - .get>('assets/gbif-default-fields.json') - .toPromise() - .then((fieldList) => { - for (const field of fieldList) { - this.gbifAttributes.push(field.name); - - const datatype = DataTypes.fromCode(field.datatype); - if (DataTypes.ALL_NUMERICS.indexOf(datatype) >= 0) { - this.gbifColumns.numeric.push(field.name); - } else { - this.gbifColumns.textual.push(field.name); - } - - this.gbifDatatypes.set(field.name, datatype); - this.gbifUnits.set(field.name, Unit.defaultUnit); - } - }); - } - - ngAfterViewInit() { - setTimeout(() => this.form.updateValueAndValidity(), 0); - } - - ngOnDestroy() { - this.subscriptions.forEach((subscription) => subscription.unsubscribe()); - } - - lookup() { - this.mode$.next(2); - this.loading$.next(true); - - const searchLevel = this.form.controls['searchLevel'].value as string; - const searchTerm = this.form.controls['searchTerm'].value as string; - - this.mappingQueryService.getGBIFDataSourceCounts(searchLevel, searchTerm).then((results) => { - this.loading$.next(false); - - let totalCount = 0; - for (const result of results) { - switch (result.name) { - case 'GBIF': - this.gbifCount = result.count; - break; - case 'IUCN': - this.iucnCount = result.count; - break; - default: - // ignore - } - totalCount += result.count; - } - }); - - this.autoCompleteTrigger.closePanel(); - } - - reset() { - this.mode$.next(1); - this.loading$.next(false); - - this.gbifCount = 0; - this.iucnCount = 0; - - this.form.controls['searchLevel'].setValue('Species'); - this.form.controls['searchTerm'].setValue(''); - - this.form.controls['select'].setValue({ - gbif: false, - iucn: false, - }); - } - - add() { - const layerName = this.form.controls['name'].value as string; - const searchLevel = this.form.controls['searchLevel'].value as string; - const searchTerm = this.form.controls['searchTerm'].value as string; - - if (this.form.controls['select'].value.iucn) { - this.addVectorLayer( - { - name: 'IUCN', - operatorType: new GFBioSourceType({ - dataSource: 'IUCN', - level: searchLevel, - term: searchTerm, - columns: this.iucnColumns, - }), - resultType: ResultTypes.POLYGONS, - }, - layerName, - ); - } - - if (this.form.controls['select'].value.gbif) { - const source = { - name: 'GBIF', - operatorType: new GFBioSourceType({ - dataSource: 'GBIF', - level: searchLevel, - term: searchTerm, - columns: this.gbifColumns, - }), - resultType: ResultTypes.POINTS, - }; - - this.addVectorLayer(source, layerName); - } - } - - addVectorLayer(source: {name: string; operatorType: OperatorType; resultType: ResultType}, layerName: string) { - const operator = new Operator({ - operatorType: source.operatorType, - resultType: source.resultType, - projection: Projections.WGS_84, - attributes: source.name === 'GBIF' ? this.gbifAttributes : this.iucnAttributes, - dataTypes: source.name === 'GBIF' ? this.gbifDatatypes : this.iucnDatatypes, - units: source.name === 'GBIF' ? this.gbifUnits : this.iucnUnits, - }); - - let symbology: AbstractVectorSymbology; - switch (source.resultType) { - case ResultTypes.POINTS: - symbology = PointSymbology.createClusterSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - break; - case ResultTypes.POLYGONS: - symbology = VectorSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - break; - default: - throw new UnexpectedResultType(); - } - - const clustered = source.resultType === ResultTypes.POINTS; - const layer = new VectorLayer({ - name: `${layerName} (${source.name})`, - operator, - symbology, - clustered, - }); - - this.projectService.addLayer(layer); - } - - addRasterLayer(source: {name: string; operatorType: OperatorType; resultType: ResultType}, layerName: string, max: number) { - const sourceOperator = new Operator({ - operatorType: source.operatorType, - resultType: source.resultType, - projection: Projections.WGS_84, - }); - - const countUnit = new Unit({ - measurement: 'count', - unit: '', - interpolation: Interpolation.Continuous, - min: 0, - max, - }); - - const heatmapOperator = new Operator({ - operatorType: new HeatmapType({ - attribute: '', - radius: 5, - }), - resultType: ResultTypes.RASTER, - projection: sourceOperator.projection, - attributes: ['value'], - dataTypes: new Map().set('value', DataTypes.UInt32), - units: new Map().set('value', countUnit), - pointSources: [sourceOperator], - }); - - this.projectService.addLayer( - new RasterLayer({ - name: `${layerName} (${source.name})`, - operator: heatmapOperator, - symbology: MappingRasterSymbology.createSymbology({ - unit: countUnit, - }), - }), - ); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/heatmap/heatmap.component.html b/projects/wave-core/src/lib/operators/dialogs/heatmap/heatmap.component.html deleted file mode 100644 index a1267b77..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/heatmap/heatmap.component.html +++ /dev/null @@ -1,22 +0,0 @@ -Heatmap -
    -
    - - - - {{ attribute.name }} - - - - - - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/heatmap/heatmap.component.scss b/projects/wave-core/src/lib/operators/dialogs/heatmap/heatmap.component.scss deleted file mode 100644 index 6200d540..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/heatmap/heatmap.component.scss +++ /dev/null @@ -1,23 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -mat-form-field { - width: 100%; -} - -.actions { - text-align: right; - padding: 1rem; -} - -.error { - color: var(--wave-warn-color, red); -} diff --git a/projects/wave-core/src/lib/operators/dialogs/heatmap/heatmap.component.ts b/projects/wave-core/src/lib/operators/dialogs/heatmap/heatmap.component.ts deleted file mode 100644 index 2209036b..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/heatmap/heatmap.component.ts +++ /dev/null @@ -1,127 +0,0 @@ -import {ChangeDetectionStrategy, Component, OnDestroy, OnInit} from '@angular/core'; - -import {RandomColorService} from '../../../util/services/random-color.service'; - -import {RasterLayer, VectorLayer} from '../../../layers/layer.model'; -import {Operator} from '../../operator.model'; -import {ResultTypes} from '../../result-type.model'; -import {AbstractVectorSymbology, MappingRasterSymbology} from '../../../layers/symbology/symbology.model'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {WaveValidators} from '../../../util/form.validators'; -import {ProjectService} from '../../../project/project.service'; -import {ReplaySubject, Subscription} from 'rxjs'; -import {DataType, DataTypes} from '../../datatype.model'; -import {HeatmapType} from '../../types/heatmap-type.model'; -import {Unit} from '../../unit.model'; - -interface AttributeType { - name: string; - value: string; -} - -/** - * This component allows creating the heatmap operator. - */ -@Component({ - selector: 'wave-heatmap', - templateUrl: './heatmap.component.html', - styleUrls: ['./heatmap.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HeatmapOperatorComponent implements OnInit, OnDestroy { - ResultTypes = ResultTypes; // make it available in the template - - form: FormGroup; - - attributes$ = new ReplaySubject>(1); - - private subscription: Subscription; - - constructor(private randomColorService: RandomColorService, private projectService: ProjectService, private formBuilder: FormBuilder) { - this.form = formBuilder.group({ - name: ['Heatmap', [Validators.required, WaveValidators.notOnlyWhitespace]], - pointLayer: [undefined, Validators.required], - attribute: [''], - radius: [10, Validators.required], - }); - } - - ngOnInit(): void { - this.subscription = this.form.controls['pointLayer'].valueChanges.subscribe((pointLayer: VectorLayer) => { - const attributes: Array = []; - pointLayer.operator.dataTypes.forEach((datatype, attribute) => { - if (DataTypes.ALL_NUMERICS.indexOf(datatype) >= 0) { - attributes.push({ - name: attribute, - value: attribute, - }); - } - }); - attributes.push({ - name: '▱ location', - value: '', - }); - this.attributes$.next(attributes); - }); - } - - ngOnDestroy(): void { - this.subscription.unsubscribe(); - } - - add(event: Event) { - event.preventDefault(); // prevent page reload on error - - if (this.form.invalid) { - return; - } - - const pointLayer: VectorLayer = this.form.controls['pointLayer'].value; - const pointOperator: Operator = pointLayer.operator; - - const attribute: string = this.form.controls['attribute'].value; - - let dataType: DataType; - if (attribute && pointOperator.dataTypes[attribute] !== null && pointOperator.dataTypes[attribute] !== undefined) { - dataType = pointOperator.dataTypes[attribute]; - } else if (attribute) { - dataType = DataTypes.Float32; - } else { - dataType = DataTypes.UInt32; - } - - let unit: Unit; - if (attribute && pointOperator.units[attribute] !== null && pointOperator.units[attribute] !== undefined) { - unit = pointOperator.units[attribute]; - } else { - unit = Unit.defaultUnit; - } - - const radius: number = this.form.controls['radius'].value; - - const name: string = this.form.controls['name'].value; - - const operator = new Operator({ - operatorType: new HeatmapType({ - attribute, - radius, - }), - resultType: ResultTypes.RASTER, - projection: pointOperator.projection, - attributes: ['value'], - dataTypes: new Map().set('value', dataType), - units: new Map().set('value', unit), - pointSources: [pointOperator], - }); - - this.projectService.addLayer( - new RasterLayer({ - name, - operator, - symbology: MappingRasterSymbology.createSymbology({ - unit, - }), - }), - ); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/layer-selection/layer-selection.component.html b/projects/wave-core/src/lib/operators/dialogs/helpers/layer-selection/layer-selection.component.html deleted file mode 100644 index d14a539a..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/layer-selection/layer-selection.component.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - {{ layer.name }} - - - -

    No Input Available

    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/layer-selection/layer-selection.component.scss b/projects/wave-core/src/lib/operators/dialogs/helpers/layer-selection/layer-selection.component.scss deleted file mode 100644 index 2d7e7bc4..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/layer-selection/layer-selection.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -mat-form-field { - width: 100%; - margin: 1rem 0; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/layer-selection/layer-selection.component.ts b/projects/wave-core/src/lib/operators/dialogs/helpers/layer-selection/layer-selection.component.ts deleted file mode 100644 index a6fe6c42..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/layer-selection/layer-selection.component.ts +++ /dev/null @@ -1,144 +0,0 @@ -import {first} from 'rxjs/operators'; -import {Observable, BehaviorSubject, ReplaySubject, Subject, Subscription} from 'rxjs'; - -import {Component, ChangeDetectionStrategy, forwardRef, Input, OnChanges, SimpleChange, OnDestroy} from '@angular/core'; -import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms'; -import {Layer} from '../../../../layers/layer.model'; -import {AbstractSymbology} from '../../../../layers/symbology/symbology.model'; -import {ResultType, ResultTypes} from '../../../result-type.model'; -import {ProjectService} from '../../../../project/project.service'; -import {LayerService} from '../../../../layers/layer.service'; - -/** - * This component allows selecting one layer. - */ -@Component({ - selector: 'wave-layer-selection', - templateUrl: './layer-selection.component.html', - styleUrls: ['./layer-selection.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - providers: [{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => LayerSelectionComponent), multi: true}], -}) -export class LayerSelectionComponent implements OnChanges, OnDestroy, ControlValueAccessor { - /** - * An array of possible layers. - */ - @Input() layers: Array> | Observable>> = this.projectService.getLayerStream(); - - /** - * The type is used as a filter for the layers to choose from. - */ - @Input() types: Array = ResultTypes.ALL_TYPES; - - /** - * The title of the component (optional). - */ - @Input() title: string = undefined; - - onTouched: () => void; - onChange: (_: Layer) => void = undefined; - - filteredLayers: Subject>> = new ReplaySubject(1); - selectedLayer = new BehaviorSubject>(undefined); - - private subscriptions: Array = []; - - constructor(private layerService: LayerService, private projectService: ProjectService) { - this.subscriptions.push( - this.filteredLayers.subscribe((filteredLayers) => { - if (filteredLayers.length > 0) { - this.selectedLayer.pipe(first()).subscribe((selectedLayer) => { - const selectedLayerIndex = filteredLayers.indexOf( - selectedLayer ? selectedLayer : this.layerService.getSelectedLayer(), - ); - if (selectedLayerIndex >= 0) { - this.selectedLayer.next(filteredLayers[selectedLayerIndex]); - } else { - this.selectedLayer.next(filteredLayers[0]); - } - }); - } else { - this.selectedLayer.next(undefined); - } - }), - ); - - this.subscriptions.push( - this.selectedLayer.subscribe((selectedLayer) => { - if (this.onChange) { - this.onChange(selectedLayer); - } - }), - ); - } - - ngOnDestroy() { - for (const subscription of this.subscriptions) { - subscription.unsubscribe(); - } - } - - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { - for (let propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - /* falls through */ - case 'layers': - case 'types': - if (this.layers instanceof Observable) { - this.layers.pipe(first()).subscribe((layers) => { - this.filteredLayers.next( - layers.filter((layer: Layer) => { - return this.types.indexOf(layer.operator.resultType) >= 0; - }), - ); - }); - } else if (this.layers instanceof Array) { - this.filteredLayers.next( - this.layers.filter((layer: Layer) => { - return this.types.indexOf(layer.operator.resultType) >= 0; - }), - ); - } - - if (this.title === undefined) { - // set title out of types - this.title = this.types - .map((type) => type.toString()) - .map((name) => (name.endsWith('s') ? name.substr(0, name.length - 1) : name)) - .join(', '); - } - - break; - default: - // do nothing - } - } - } - - onBlur() { - if (this.onTouched) { - this.onTouched(); - } - } - - writeValue(layer: Layer): void { - if (layer !== null) { - this.selectedLayer.next(layer); - } - } - - registerOnChange(fn: (_: Layer) => void): void { - this.onChange = fn; - - this.onChange(this.selectedLayer.getValue()); - } - - registerOnTouched(fn: () => void): void { - this.onTouched = fn; - } - - setSelectedLayer(layer: Layer) { - this.selectedLayer.next(layer); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/multi-layer-selection/multi-layer-selection.component.html b/projects/wave-core/src/lib/operators/dialogs/helpers/multi-layer-selection/multi-layer-selection.component.html deleted file mode 100644 index 6e3ba984..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/multi-layer-selection/multi-layer-selection.component.html +++ /dev/null @@ -1,40 +0,0 @@ -
    - -
    - - -
    -
    -
    - - - {{ layer.name }} - - -
    - -

    No Input Available

    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/multi-layer-selection/multi-layer-selection.component.scss b/projects/wave-core/src/lib/operators/dialogs/helpers/multi-layer-selection/multi-layer-selection.component.scss deleted file mode 100644 index ee60bd6a..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/multi-layer-selection/multi-layer-selection.component.scss +++ /dev/null @@ -1,13 +0,0 @@ -:host { - display: block; - padding-bottom: 1em; -} - -mat-form-field { - margin: 0.5rem 0 1rem 0; -} - -button { - min-width: unset; - margin-top: 1rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/multi-layer-selection/multi-layer-selection.component.ts b/projects/wave-core/src/lib/operators/dialogs/helpers/multi-layer-selection/multi-layer-selection.component.ts deleted file mode 100644 index e53936e2..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/multi-layer-selection/multi-layer-selection.component.ts +++ /dev/null @@ -1,252 +0,0 @@ -import {combineLatest as observableCombineLatest, Observable, ReplaySubject, Subject, BehaviorSubject, Subscription} from 'rxjs'; - -import {first} from 'rxjs/operators'; -import {Component, ChangeDetectionStrategy, forwardRef, SimpleChange, Input, OnChanges, OnDestroy} from '@angular/core'; -import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms'; -import {Layer} from '../../../../layers/layer.model'; -import {AbstractSymbology} from '../../../../layers/symbology/symbology.model'; -import {ResultType} from '../../../result-type.model'; -import {ProjectService} from '../../../../project/project.service'; -import {LayerService} from '../../../../layers/layer.service'; - -/** - * Singleton for a letter to number converter for ids. - */ -export const LetterNumberConverter = { - // eslint-disable-line @typescript-eslint/naming-convention, no-underscore-dangle, id-blacklist, id-match - /** - * Convert a numeric id to a alphanumeric one. - * Starting with `1`. - */ - toLetters: (num: number) => { - const mod = num % 26; - let pow = (num / 26) | 0; // eslint-disable-line no-bitwise - // noinspection CommaExpressionJS - const out = mod ? String.fromCharCode(64 + mod) : (--pow, 'Z'); - return pow ? LetterNumberConverter.toLetters(pow) + out : out; - }, - - /** - * Convert an alphanumeric id to a numeric one. - * Starting with `A`. - */ - fromLetters: (str: string) => { - let out = 0; - const len = str.length; - let pos = len; - while (--pos > -1) { - out += (str.charCodeAt(pos) - 64) * Math.pow(26, len - 1 - pos); - } - return out; - }, -}; - -@Component({ - selector: 'wave-multi-layer-selection', - templateUrl: './multi-layer-selection.component.html', - styleUrls: ['./multi-layer-selection.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - providers: [{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MultiLayerSelectionComponent), multi: true}], -}) -export class MultiLayerSelectionComponent implements ControlValueAccessor, OnChanges, OnDestroy { - /** - * An array of possible layers. - */ - @Input() layers: Array> | Observable>> = this.projectService.getLayerStream(); - - /** - * The minimum number of elements to select. - */ - @Input() min = 1; - - /** - * The maximum number of elements to select. - */ - @Input() max = 1; - - /** - * The initial amount of elements to select. - */ - @Input() initialAmount = 1; - - /** - * The type is used as a filter for the layers to choose from. - */ - @Input() types: Array; - - /** - * The title of the component (optional). - */ - @Input() title: string = undefined; - - onTouched: () => void; - onChange: (_: Array>) => void = undefined; - - filteredLayers: Subject>> = new ReplaySubject(1); - selectedLayers = new BehaviorSubject>>([]); - - private layerSubscription: Subscription; - private selectionSubscription: Subscription; - - constructor(private projectService: ProjectService, private layerService: LayerService) { - this.layerSubscription = this.filteredLayers.subscribe((filteredLayers) => { - this.selectedLayers.next(this.layersForInitialSelection(filteredLayers, [], this.initialAmount)); - }); - - this.selectionSubscription = this.selectedLayers.subscribe((selectedLayers) => { - if (this.onChange) { - this.onChange(selectedLayers); - } - }); - } - - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { - let minMaxInitialChanged = false; - let initialChange = false; - - for (const propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - case 'initialAmount': - initialChange = changes[propName].isFirstChange(); - /* falls through */ - case 'min': - case 'max': - minMaxInitialChanged = true; - break; - case 'layers': - case 'types': - if (this.layers instanceof Observable) { - this.layers.pipe(first()).subscribe((layers) => { - this.filteredLayers.next( - layers.filter((layer: Layer) => { - return this.types.indexOf(layer.operator.resultType) >= 0; - }), - ); - }); - } else if (this.layers instanceof Array) { - this.filteredLayers.next( - this.layers.filter((layer: Layer) => { - return this.types.indexOf(layer.operator.resultType) >= 0; - }), - ); - } - - if (this.title === undefined) { - this.title = this.types.map((type) => type.toString()).join(', '); - } - break; - - default: - // DO NOTHING - } - } - - if (minMaxInitialChanged) { - observableCombineLatest(this.filteredLayers, this.selectedLayers) - .pipe(first()) - .subscribe(([filteredLayers, selectedLayers]) => { - const amountOfLayers = selectedLayers.length; - - if (this.max < amountOfLayers) { - // remove selected layers - const difference = amountOfLayers - this.max; - this.selectedLayers.next(selectedLayers.slice(0, amountOfLayers - difference)); - } else if (this.min > amountOfLayers) { - // add selected layers - const difference = this.min - amountOfLayers; - this.selectedLayers.next(selectedLayers.concat(this.layersForInitialSelection(filteredLayers, [], difference))); - } - - if (initialChange) { - // set initial layers - this.selectedLayers.next(this.layersForInitialSelection(filteredLayers, [], this.initialAmount)); - } - }); - } - } - - ngOnDestroy() { - this.layerSubscription.unsubscribe(); - this.selectionSubscription.unsubscribe(); - } - - updateLayer(index: number, layer: Layer) { - this.selectedLayers.pipe(first()).subscribe((selectedLayers) => { - const newSelectedLayers = [...selectedLayers]; - newSelectedLayers[index] = layer; - this.selectedLayers.next(newSelectedLayers); - }); - } - - add() { - observableCombineLatest(this.filteredLayers, this.selectedLayers) - .pipe(first()) - .subscribe(([filteredLayers, selectedLayers]) => { - this.selectedLayers.next(selectedLayers.concat(this.layersForInitialSelection(filteredLayers, selectedLayers, 1))); - - this.onBlur(); - }); - } - - remove() { - this.selectedLayers.pipe(first()).subscribe((selectedLayers) => { - this.selectedLayers.next(selectedLayers.slice(0, selectedLayers.length - 1)); - - this.onBlur(); - }); - } - - onBlur() { - if (this.onTouched) { - this.onTouched(); - } - } - - writeValue(layers: Array>): void { - if (layers) { - this.selectedLayers.next(layers); - } else if (this.onChange) { - this.onChange(this.selectedLayers.getValue()); - } - } - - registerOnChange(fn: (_: Array>) => void): void { - this.onChange = fn; - - this.onChange(this.selectedLayers.getValue()); - } - - registerOnTouched(fn: () => void): void { - this.onTouched = fn; - } - - // noinspection JSMethodCanBeStatic - toLetters(i: number): string { - return LetterNumberConverter.toLetters(i + 1); - } - - private layersForInitialSelection( - layers: Array>, - blacklist: Array>, - amount: number, - ): Array> { - if (layers.length === 0) { - return []; - } - - const layersForSelection = [...layers].filter((layer) => blacklist.indexOf(layer) < 0); - - const selectedLayerIndex = layersForSelection.indexOf(this.layerService.getSelectedLayer()); - if (selectedLayerIndex >= 0) { - // swap to front - layersForSelection[0] = layersForSelection.splice(selectedLayerIndex, 1, layersForSelection[0])[0]; - } - - while (layersForSelection.length < amount) { - layersForSelection.push(layers[0]); - } - - return layersForSelection.slice(0, amount); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/operator-output-name/operator-output-name.component.html b/projects/wave-core/src/lib/operators/dialogs/helpers/operator-output-name/operator-output-name.component.html deleted file mode 100644 index 1974eb2c..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/operator-output-name/operator-output-name.component.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/operator-output-name/operator-output-name.component.scss b/projects/wave-core/src/lib/operators/dialogs/helpers/operator-output-name/operator-output-name.component.scss deleted file mode 100644 index bc76a27e..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/operator-output-name/operator-output-name.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -mat-form-field { - width: 100%; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/operator-output-name/operator-output-name.component.ts b/projects/wave-core/src/lib/operators/dialogs/helpers/operator-output-name/operator-output-name.component.ts deleted file mode 100644 index 91ece8b9..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/operator-output-name/operator-output-name.component.ts +++ /dev/null @@ -1,81 +0,0 @@ -import {Component, ChangeDetectionStrategy, OnChanges, SimpleChange, ChangeDetectorRef, Input, AfterViewInit} from '@angular/core'; -import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms'; - -@Component({ - selector: 'wave-operator-output-name', - templateUrl: './operator-output-name.component.html', - styleUrls: ['./operator-output-name.component.scss'], - providers: [{provide: NG_VALUE_ACCESSOR, useExisting: OperatorOutputNameComponent, multi: true}], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class OperatorOutputNameComponent implements ControlValueAccessor, OnChanges, AfterViewInit { - @Input() type: 'Layer' | 'Plot' = 'Layer'; - @Input() suggestion = ''; - - private _name: string; - private userChanged = false; - - private onTouched: () => void; - private onChange: (_: string) => void = undefined; - - constructor(private changeDetectorRef: ChangeDetectorRef) {} - - set name(name: string) { - this._name = name; - this.userChanged = true; - if (this.onChange) { - this.onChange(name); - } - } - - get name(): string { - return this._name; - } - - ngAfterViewInit() { - // once for rendering the input properly - setTimeout(() => this.changeDetectorRef.markForCheck()); - } - - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { - for (let propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - case 'suggestion': - if (!this.userChanged) { - this._name = this.suggestion; - - if (this.onChange) { - this.onChange(this._name); - } - this.changeDetectorRef.markForCheck(); - } - break; - default: - // do nothing - } - } - } - - /** Implemented as part of ControlValueAccessor. */ - writeValue(value: string): void { - this._name = value; - this.changeDetectorRef.markForCheck(); - } - - /** Implemented as part of ControlValueAccessor. */ - registerOnChange(fn: () => {}) { - this.onChange = fn; - } - - /** Implemented as part of ControlValueAccessor. */ - registerOnTouched(fn: () => {}) { - this.onTouched = fn; - } - - onBlur() { - if (this.onTouched) { - this.onTouched(); - } - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/reprojection-selection/reprojection-selection.component.html b/projects/wave-core/src/lib/operators/dialogs/helpers/reprojection-selection/reprojection-selection.component.html deleted file mode 100644 index 22b7879d..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/reprojection-selection/reprojection-selection.component.html +++ /dev/null @@ -1,6 +0,0 @@ - - - {{ projection }} - - -

    No Projection Available

    diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/reprojection-selection/reprojection-selection.component.scss b/projects/wave-core/src/lib/operators/dialogs/helpers/reprojection-selection/reprojection-selection.component.scss deleted file mode 100644 index bc76a27e..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/reprojection-selection/reprojection-selection.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -mat-form-field { - width: 100%; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/helpers/reprojection-selection/reprojection-selection.component.ts b/projects/wave-core/src/lib/operators/dialogs/helpers/reprojection-selection/reprojection-selection.component.ts deleted file mode 100644 index 3680ee3b..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/helpers/reprojection-selection/reprojection-selection.component.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { - Component, - ChangeDetectionStrategy, - forwardRef, - AfterViewInit, - OnChanges, - SimpleChange, - ChangeDetectorRef, - Input, -} from '@angular/core'; -import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms'; -import {Projection} from '../../../projection.model'; -import {Layer} from '../../../../layers/layer.model'; -import {AbstractSymbology} from '../../../../layers/symbology/symbology.model'; - -@Component({ - selector: 'wave-reprojection-selection', - templateUrl: './reprojection-selection.component.html', - styleUrls: ['./reprojection-selection.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - providers: [{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ReprojectionSelectionComponent), multi: true}], -}) -export class ReprojectionSelectionComponent implements OnChanges, ControlValueAccessor { - /** - * An array of layers that is traversed to get all projections. - */ - @Input() layers: Array>; - - projections: Array; - selectedProjection: Projection; - - private onTouched: () => void; - private onChange: (_: Projection) => void = undefined; - - private firstUndefined = true; - - constructor(private changeDetectorRef: ChangeDetectorRef) {} - - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { - for (let propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - case 'layers': - this.projections = []; - if (this.layers) { - for (const layer of this.layers) { - let projection = layer.operator.projection; - if (this.projections.indexOf(projection) === -1) { - this.projections.push(projection); - } - } - if (this.projections.length > 0 && this.projections.indexOf(this.selectedProjection) < 0) { - this.selectedProjection = this.layers[0].operator.projection; - if (this.onChange) { - this.onChange(this.selectedProjection); - } - } - } else { - this.selectedProjection = undefined; - } - - setTimeout(() => this.changeDetectorRef.markForCheck()); - break; - default: - // DO NOTHING - } - } - } - - /** - * Informs the component when we lose focus in order to style accordingly - * @internal - */ - onBlur() { - this.onTouched(); - } - - /** - * Implemented as part of ControlValueAccessor. - */ - writeValue(value: Projection) { - if (this.firstUndefined && !value) { - this.firstUndefined = false; - } else { - this.selectedProjection = value; - } - - this.changeDetectorRef.markForCheck(); - } - - /** - * Implemented as part of ControlValueAccessor. - */ - registerOnChange(fn: (_: Projection) => void): void { - this.onChange = fn; - - if (this.selectedProjection) { - this.onChange(this.selectedProjection); - } - } - - /** - * Implemented as part of ControlValueAccessor. - */ - registerOnTouched(fn: () => {}) { - this.onTouched = fn; - } - - selectProjection(projection: Projection) { - this.selectedProjection = projection; - if (this.onChange) { - this.onChange(projection); - } - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/histogram-operator/histogram-operator.component.html b/projects/wave-core/src/lib/operators/dialogs/histogram-operator/histogram-operator.component.html deleted file mode 100644 index bbe84662..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/histogram-operator/histogram-operator.component.html +++ /dev/null @@ -1,60 +0,0 @@ -Histogram - - -

    - This operator generates a Histogram based on a raster or vector data set (Input). Select the Range Type, which - can be the pixel values of a raster layer or the attribute values of vector data. The histogram shows the frequency of values - (y-axis) in a certain range on the x-axis. This range is defined by the number of buckets, i.e., if you choose a bucket number of - 20, the value range between min/max values is divided into 20 sections, each covering a value range of equal size. This is done - automatically if you tick the box Choose number of buckets automatically. Edit the Output Name of the plot, if - desired, and click on Create to generate the plot. -

    -

    Note: Plots change dynamically with the map view and include only pixels or features, which are located in this area.

    -
    - -
    -
    - - - - - {{ attribute }} - - - - - Custom - Unit - Data - - -
    - - - Please specify the value. - -
    - - - - The maximum must be greater or equal to the minimum. - - Please specify the value. - -
    - Choose number of buckets automatically -
    - - - -
    - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/histogram-operator/histogram-operator.component.scss b/projects/wave-core/src/lib/operators/dialogs/histogram-operator/histogram-operator.component.scss deleted file mode 100644 index 8a6c6092..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/histogram-operator/histogram-operator.component.scss +++ /dev/null @@ -1,30 +0,0 @@ -:host { - display: block; - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.actions { - text-align: right; - padding: 1rem; -} - -mat-form-field { - width: 100%; - margin: 1rem 0; -} - -.error { - color: var(--wave-warn-color, red); -} - -div { - padding-bottom: 0.5rem; - padding-top: 1rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/histogram-operator/histogram-operator.component.ts b/projects/wave-core/src/lib/operators/dialogs/histogram-operator/histogram-operator.component.ts deleted file mode 100644 index a6a64421..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/histogram-operator/histogram-operator.component.ts +++ /dev/null @@ -1,156 +0,0 @@ -import {Subscription, ReplaySubject, Observable} from 'rxjs'; -import {map, tap} from 'rxjs/operators'; -import {Component, ChangeDetectionStrategy, OnInit, OnDestroy, AfterViewInit} from '@angular/core'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {DataTypes, DataType} from '../../datatype.model'; -import {WaveValidators} from '../../../util/form.validators'; -import {Layer} from '../../../layers/layer.model'; -import {AbstractSymbology} from '../../../layers/symbology/symbology.model'; -import {HistogramType} from '../../types/histogram-type.model'; -import {Operator} from '../../operator.model'; -import {ResultTypes} from '../../result-type.model'; -import {Unit} from '../../unit.model'; -import {Plot} from '../../../plots/plot.model'; -import {ProjectService} from '../../../project/project.service'; - -/** - * Checks whether the layer is a vector layer (points, lines, polygons). - */ -function isVectorLayer(layer: Layer): boolean { - return layer ? ResultTypes.VECTOR_TYPES.indexOf(layer.operator.resultType) >= 0 : false; -} - -/** - * This dialog allows creating a histogram plot of a layer's values. - */ -@Component({ - selector: 'wave-histogram-operator', - templateUrl: './histogram-operator.component.html', - styleUrls: ['./histogram-operator.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HistogramOperatorComponent implements OnInit, AfterViewInit, OnDestroy { - // make public to template - ResultTypes = ResultTypes; - // - - form: FormGroup; - - attributes$ = new ReplaySubject>(1); - - isVectorLayer$: Observable; - - private subscriptions: Array = []; - - /** - * DI for services - */ - constructor(private projectService: ProjectService, private formBuilder: FormBuilder) {} - - ngOnInit() { - const layerControl = this.formBuilder.control(undefined, Validators.required); - let rangeTypeControl = this.formBuilder.control('data', Validators.required); - this.form = this.formBuilder.group({ - name: ['Filtered Values', [Validators.required, WaveValidators.notOnlyWhitespace]], - layer: layerControl, - attribute: [undefined, WaveValidators.conditionalValidator(Validators.required, () => isVectorLayer(layerControl.value))], - rangeType: rangeTypeControl, - range: this.formBuilder.group( - { - min: [undefined], - max: [undefined], - }, - { - validator: WaveValidators.conditionalValidator( - WaveValidators.minAndMax('min', 'max', {checkBothExist: true}), - () => rangeTypeControl.value === 'custom', - ), - }, - ), - autoBuckets: [true, Validators.required], - numberOfBuckets: [20, Validators.required], - }); - - this.subscriptions.push( - this.form.controls['layer'].valueChanges - .pipe( - tap(() => this.form.controls['attribute'].setValue(undefined)), - map((layer) => { - if (layer) { - return layer.operator.attributes - .filter((attribute: string) => { - return DataTypes.ALL_NUMERICS.indexOf(layer.operator.dataTypes.get(attribute)) >= 0; - }) - .toArray(); - } else { - return []; - } - }), - ) - .subscribe(this.attributes$), - ); - - this.subscriptions.push( - this.form.controls['rangeType'].valueChanges.subscribe(() => this.form.controls['range'].updateValueAndValidity()), - ); - - this.isVectorLayer$ = this.form.controls['layer'].valueChanges.pipe(map((layer) => isVectorLayer(layer))); - } - - ngAfterViewInit() { - setTimeout(() => { - this.form.updateValueAndValidity(); - this.form.controls['layer'].updateValueAndValidity(); - }); - } - - ngOnDestroy() { - this.subscriptions.forEach((subscription) => subscription.unsubscribe()); - } - - /** - * Uses the user input to create a histogram plot. - * The plot is added to the plot view. - */ - add(event: any) { - const inputOperator = (this.form.controls['layer'].value as Layer).operator; - - const attributeName = this.form.controls['attribute'].value as string; - - let range: {min: number; max: number} | string = this.form.controls['rangeType'].value as string; - if (range === 'custom') { - range = this.form.controls['range'].value as {min: number; max: number}; - } - - let buckets: number = undefined; - if (!this.form.controls['autoBuckets'].value) { - buckets = this.form.controls['numberOfBuckets'].value as number; - } - - const outputName: string = this.form.controls['name'].value; - - const operator = new Operator({ - operatorType: new HistogramType({ - attribute: attributeName, - range: range, - buckets: buckets, - }), - resultType: ResultTypes.PLOT, - projection: inputOperator.projection, - attributes: [], - dataTypes: new Map(), - units: new Map(), - rasterSources: inputOperator.resultType === ResultTypes.RASTER ? [inputOperator] : [], - pointSources: inputOperator.resultType === ResultTypes.POINTS ? [inputOperator] : [], - lineSources: inputOperator.resultType === ResultTypes.LINES ? [inputOperator] : [], - polygonSources: inputOperator.resultType === ResultTypes.POLYGONS ? [inputOperator] : [], - }); - - this.projectService.addPlot( - new Plot({ - name: outputName, - operator: operator, - }), - ); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/numeric-attribute-filter/numeric-attribute-filter.component.html b/projects/wave-core/src/lib/operators/dialogs/numeric-attribute-filter/numeric-attribute-filter.component.html deleted file mode 100644 index bdedd5a3..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/numeric-attribute-filter/numeric-attribute-filter.component.html +++ /dev/null @@ -1,73 +0,0 @@ -Numeric Attribute Filter -
    -
    - - -
    - - - {{ attribute }} - - -
    - - -
    - - Min - - {{ attributeUnit$ | async }} - - Specify at least minimum or maximum. - - - - Max - - {{ attributeUnit$ | async }} - - The maximum must be greater or equal to the minimum. - - -
    - Keep NoData values? - - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/numeric-attribute-filter/numeric-attribute-filter.component.scss b/projects/wave-core/src/lib/operators/dialogs/numeric-attribute-filter/numeric-attribute-filter.component.scss deleted file mode 100644 index d00a0aee..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/numeric-attribute-filter/numeric-attribute-filter.component.scss +++ /dev/null @@ -1,40 +0,0 @@ -$circle-width: 100px; - -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -.actions { - text-align: right; - padding: 1rem; -} - -mat-progress-spinner { - position: relative; - left: calc(50% - #{$circle-width / 2}); - width: $circle-width; -} - -mat-form-field { - width: 100%; - margin: 1rem 0; -} - -mat-form-field { - margin-bottom: 1rem; -} - -mat-form-field:not(:last-child) { - margin-right: 1rem; -} - -.downward-margin { - margin-bottom: 1rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/numeric-attribute-filter/numeric-attribute-filter.component.ts b/projects/wave-core/src/lib/operators/dialogs/numeric-attribute-filter/numeric-attribute-filter.component.ts deleted file mode 100644 index 68afc3ff..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/numeric-attribute-filter/numeric-attribute-filter.component.ts +++ /dev/null @@ -1,233 +0,0 @@ -import {BehaviorSubject, Observable, Subscription, combineLatest} from 'rxjs'; -import {first, map} from 'rxjs/operators'; -import {AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, OnDestroy} from '@angular/core'; -import {HistogramData} from '../../../plots/histogram/histogram.component'; -import {RandomColorService} from '../../../util/services/random-color.service'; -import {MappingQueryService} from '../../../queries/mapping-query.service'; -import {VectorLayer} from '../../../layers/layer.model'; -import {ResultTypes} from '../../result-type.model'; -import {DataType, DataTypes} from '../../datatype.model'; -import {AbstractVectorSymbology} from '../../../layers/symbology/symbology.model'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {Operator} from '../../operator.model'; -import {NumericAttributeFilterType} from '../../types/numeric-attribute-filter-type.model'; -import {HistogramType} from '../../types/histogram-type.model'; -import {Unit} from '../../unit.model'; -import {ProjectService} from '../../../project/project.service'; -import {LayoutService} from '../../../layout.service'; -import {WaveValidators} from '../../../util/form.validators'; -import {MapService} from '../../../map/map.service'; - -/** - * This component allows creating the numeric attribute filter operator. - */ -@Component({ - selector: 'wave-numeric-attribute-filter', - templateUrl: './numeric-attribute-filter.component.html', - styleUrls: ['./numeric-attribute-filter.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class NumericAttributeFilterOperatorComponent implements AfterViewInit, OnDestroy { - readonly ResultTypes = ResultTypes; - - readonly form: FormGroup; - readonly attributes$: Observable>; - readonly data$: BehaviorSubject = new BehaviorSubject(undefined); - readonly dataLoading$ = new BehaviorSubject(false); - readonly attributeUnit$ = new BehaviorSubject(''); - - histogramWidth: number; - histogramHeight: number; - - private subscriptions: Array = []; - - constructor( - private randomColorService: RandomColorService, - private mappingQueryService: MappingQueryService, - private projectService: ProjectService, - private mapService: MapService, - private formBuilder: FormBuilder, - private elementRef: ElementRef, - ) { - this.form = formBuilder.group({ - name: ['Filtered Values', [Validators.required, WaveValidators.notOnlyWhitespace]], - inputLayer: [undefined, Validators.required], - attribute: [undefined, Validators.required], - bounds: formBuilder.group( - { - min: [undefined], - max: [undefined], - }, - { - validator: WaveValidators.minAndMax('min', 'max'), - }, - ), - noData: [false, Validators.required], - }); - - this.subscriptions.push( - this.form.controls['attribute'].valueChanges.subscribe((attribute: string) => { - if (!attribute) { - this.data$.next(undefined); - return; - } - - const vectorLayer: VectorLayer = this.form.controls['inputLayer'].value; - - const operator = new Operator({ - operatorType: new HistogramType({ - attribute: attribute, - range: 'data', - }), - resultType: ResultTypes.PLOT, - projection: vectorLayer.operator.projection, - attributes: [], - dataTypes: new Map(), - units: new Map(), - pointSources: vectorLayer.operator.resultType === ResultTypes.POINTS ? [vectorLayer.operator] : [], - lineSources: vectorLayer.operator.resultType === ResultTypes.LINES ? [vectorLayer.operator] : [], - polygonSources: vectorLayer.operator.resultType === ResultTypes.POLYGONS ? [vectorLayer.operator] : [], - }); - - this.dataLoading$.next(true); - - combineLatest([ - this.projectService.getTimeStream().pipe(first()), - this.projectService.getProjectionStream().pipe(first()), - ]).subscribe(([projectTime, projection]) => { - this.mappingQueryService - .getPlotData({ - operator: operator, - time: projectTime, - extent: this.mapService.getViewportSize().extent, - projection: projection, - }) - .subscribe((data) => { - this.data$.next(data as HistogramData); - this.dataLoading$.next(false); - }); - }); - }), - ); - - this.attributes$ = this.form.controls['inputLayer'].valueChanges.pipe( - map((layer) => { - // side effect!!! - this.form.controls['attribute'].setValue(undefined); - - if (layer) { - this.form.controls['attribute'].enable({onlySelf: true}); - return layer.operator.attributes - .filter((attribute: string) => { - return DataTypes.ALL_NUMERICS.indexOf(layer.operator.dataTypes.get(attribute)) >= 0; - }) - .toArray(); - } else { - this.form.controls['attribute'].disable({onlySelf: true}); - return []; - } - }), - ); - - this.subscriptions.push( - this.form.controls['attribute'].valueChanges - .pipe( - map((attribute: string) => { - if (!attribute) { - return ''; - } - - const operator = this.form.controls['inputLayer'].value.operator as Operator; - const unit = operator.getUnit(attribute); - - if (!unit || unit.unit === Unit.defaultUnit.unit || unit.measurement === Unit.defaultUnit.measurement) { - return ''; - } else { - return unit.unit; - } - }), - ) - .subscribe((unit) => this.attributeUnit$.next(unit)), - ); - } - - ngAfterViewInit() { - // calculate size for histogram - const formStyle = getComputedStyle(this.elementRef.nativeElement.querySelector('form')); - const formWidth = parseInt(formStyle.width, 10) - 2 * LayoutService.remInPx - LayoutService.scrollbarWidthPx(); - const formHeight = parseInt(formStyle.height, 10) - 2 * LayoutService.remInPx; - - this.histogramWidth = formWidth; - this.histogramHeight = Math.max(formHeight / 3, formWidth / 3); - - // initially get attributes - setTimeout(() => this.form.controls['inputLayer'].enable({emitEvent: true})); - } - - ngOnDestroy() { - this.subscriptions.forEach((subscription) => subscription.unsubscribe()); - } - - add(_event: any) { - const vectorLayer: VectorLayer = this.form.controls['inputLayer'].value; - const vectorOperator: Operator = vectorLayer.operator; - - const units = vectorOperator.units; - const dataTypes = vectorOperator.dataTypes; - const attributes = vectorOperator.attributes; - - const noData: boolean = this.form.controls['noData'].value; - const attributeName: string = this.form.controls['attribute'].value; - const boundsMin: number = this.form.controls['bounds'].value.min; - const boundsMax: number = this.form.controls['bounds'].value.max; - - const name: string = this.form.controls['name'].value; - - const dict = { - operatorType: new NumericAttributeFilterType({ - attributeName: attributeName, - includeNoData: noData, - rangeMin: boundsMin === null ? undefined : boundsMin, - rangeMax: boundsMax === null ? undefined : boundsMax, - }), - resultType: vectorOperator.resultType, - projection: vectorOperator.projection, - attributes: attributes, - dataTypes: dataTypes, - units: units, - pointSources: [], - lineSources: [], - polygonSources: [], - }; - - switch (vectorOperator.resultType) { - case ResultTypes.POINTS: - dict.pointSources.push(vectorOperator); - break; - case ResultTypes.LINES: - dict.lineSources.push(vectorOperator); - break; - case ResultTypes.POLYGONS: - dict.polygonSources.push(vectorOperator); - break; - default: - throw Error('Incompatible Input Type'); - } - - const operator = new Operator(dict); - - const symbology = (vectorLayer.symbology.clone() as any) as AbstractVectorSymbology; - symbology.fillRGBA = this.randomColorService.getRandomColorRgba(); - - const clustered = vectorLayer.clustered; - - const layer = new VectorLayer({ - name: name, - operator: operator, - symbology, - clustered, - }); - - this.projectService.addLayer(layer); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/operator-list/operator-list.component.html b/projects/wave-core/src/lib/operators/dialogs/operator-list/operator-list.component.html deleted file mode 100644 index 5ce45fbe..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/operator-list/operator-list.component.html +++ /dev/null @@ -1,14 +0,0 @@ -Operators - - - -

    {{ group.name }}

    - - - -

    -

    -
    -
    -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/operator-list/operator-list.component.scss b/projects/wave-core/src/lib/operators/dialogs/operator-list/operator-list.component.scss deleted file mode 100644 index 8a7e8651..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/operator-list/operator-list.component.scss +++ /dev/null @@ -1,7 +0,0 @@ -p { - color: var(--wave-foreground-secondary-text-color, grey); -} - -mat-list-item ::ng-deep .highlight { - color: var(--wave-accent-color, grey); -} diff --git a/projects/wave-core/src/lib/operators/dialogs/operator-list/operator-list.component.ts b/projects/wave-core/src/lib/operators/dialogs/operator-list/operator-list.component.ts deleted file mode 100644 index aa788e58..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/operator-list/operator-list.component.ts +++ /dev/null @@ -1,231 +0,0 @@ -import {BehaviorSubject, combineLatest, Observable, of} from 'rxjs'; -import {map} from 'rxjs/operators'; - -import {ChangeDetectionStrategy, Component, Input, OnInit, Type} from '@angular/core'; -import {RasterValueExtractionType} from '../../types/raster-value-extraction-type.model'; - -import {NumericAttributeFilterType} from '../../types/numeric-attribute-filter-type.model'; -import {NumericAttributeFilterOperatorComponent} from '../numeric-attribute-filter/numeric-attribute-filter.component'; - -import {PointInPolygonFilterType} from '../../types/point-in-polygon-filter-type.model'; -import {PointInPolygonFilterOperatorComponent} from '../point-in-polygon-filter/point-in-polygon-filter.component'; - -import {ExpressionOperatorComponent} from '../expression-operator/expression-operator.component'; -import {ExpressionType} from '../../types/expression-type.model'; - -import {HistogramType} from '../../types/histogram-type.model'; -import {RasterValueExtractionOperatorComponent} from '../raster-value-extraction/raster-value-extraction.component'; -import {HistogramOperatorComponent} from '../histogram-operator/histogram-operator.component'; -import {LayoutService} from '../../../layout.service'; -import {ROperatorComponent} from '../r/r-operator/r-operator.component'; -import {RScriptType} from '../../types/r-script-type.model'; -import {PieChartComponent} from '../pie-chart-operator/pie-chart-operator.component'; -import {PieChartType} from '../../types/piechart-type.model'; -import {ScatterPlotComponent} from '../scatter-plot-operator/scatter-plot-operator.component'; -import {ScatterPlotType} from '../../types/scatterplot-type.model'; -import {TextualAttributeFilterOperatorComponent} from '../textual-attribute-filter/textual-attribute-filter.component'; -import {TextualAttributeFilterType} from '../../types/textual-attribute-filter-type.model'; -import {BoxPlotComponent} from '../box-plot-operator/box-plot-operator.component'; -import {BoxPlotType} from '../../types/boxplot-type.model'; -import {RasterPolygonClipOperatorComponent} from '../raster-polygon-clip/raster-polygon-clip.component'; -import {OperatorType} from '../../operator-type.model'; -import {HeatmapOperatorComponent} from '../heatmap/heatmap.component'; -import {HeatmapType} from '../../types/heatmap-type.model'; -import {TimePlotType} from '../../types/timeplot-type.model'; -import {TimePlotComponent} from '../time-plot-operator/time-plot-operator.component'; -import {StatisticsType} from '../../types/statistics-type.model'; -import {StatisticsPlotComponent} from '../statistics-plot/statistics-plot.component'; -import {RgbCompositeComponent} from '../rgb-composite/rgb-composite.component'; -import {RgbaCompositeType} from '../../types/rgba-composite-type.model'; -import {RasterMaskComponent} from '../raster-mask/raster-mask.component'; - -/** - * This type encapsulates… - * * a component to select, - * * a type to display (name and icon) and - * * a short description text. - */ -export interface OperatorListType { - component: Type; - type: {NAME: string; ICON_URL: string}; - description: string; -} - -/** - * This types groups operator list types - */ -export type OperatorListButtonGroups = Array<{ - name: string; - list: Array; -}>; - -/** - * This component provides a list of operator dialogs to choose from. - * - * It provides a set of default operators but they can be overridden. - */ -@Component({ - selector: 'wave-operator-list', - templateUrl: './operator-list.component.html', - styleUrls: ['./operator-list.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class OperatorListComponent implements OnInit { - static readonly DEFAULT_MIXED_OPERATOR_DIALOGS: Array = [ - { - component: RasterValueExtractionOperatorComponent, - type: RasterValueExtractionType, - description: 'Attach raster values to vector data', - }, - { - component: RasterPolygonClipOperatorComponent, - type: { - NAME: 'Raster Polygon Clip', - ICON_URL: OperatorType.createIconDataUrl('Raster Polygon Clip'), - }, - description: 'Clip a raster image via polygon boundaries', - }, - { - component: ROperatorComponent, - type: RScriptType, - description: 'Execute an R script (experimental)', - }, - ]; - - static readonly DEFAULT_PLOT_OPERATOR_DIALOGS: Array = [ - { - component: HistogramOperatorComponent, - type: HistogramType, - description: 'Create a histogram from vector or raster data', - }, - { - component: PieChartComponent, - type: PieChartType, - description: 'Plot your data as a pie chart', - }, - { - component: ScatterPlotComponent, - type: ScatterPlotType, - description: 'Scatter plot your data', - }, - { - component: BoxPlotComponent, - type: BoxPlotType, - description: 'Box plot your data', - }, - { - component: StatisticsPlotComponent, - type: StatisticsType, - description: 'Get statistics for any layer', - }, - { - component: TimePlotComponent, - type: TimePlotType, - description: 'Plot time data', - }, - ]; - - static readonly DEFAULT_RASTER_OPERATOR_DIALOGS: Array = [ - { - component: ExpressionOperatorComponent, - type: ExpressionType, - description: 'Calculate an expression on a raster', - }, - { - component: RasterMaskComponent, - type: { - NAME: 'Raster Mask', - ICON_URL: OperatorType.createIconDataUrl('Raster Mask'), - }, - description: 'Apply a mask to a raster', - }, - { - component: RgbCompositeComponent, - type: RgbaCompositeType, - description: 'Create an RGB composite from a set of rasters', - }, - ]; - - static readonly DEFAULT_VECTOR_OPERATOR_DIALOGS: Array = [ - { - component: NumericAttributeFilterOperatorComponent, - type: NumericAttributeFilterType, - description: 'Filter data via numeric range', - }, - { - component: HeatmapOperatorComponent, - type: HeatmapType, - description: 'Create a heatmap for points', - }, - { - component: PointInPolygonFilterOperatorComponent, - type: PointInPolygonFilterType, - description: 'Filter points that are enclosed by a polygon', - }, - { - component: TextualAttributeFilterOperatorComponent, - type: TextualAttributeFilterType, - description: 'Filter data via text filter', - }, - ]; - - /** - * Specify (optionally) a custom set of operator groups and list entries (buttons) - */ - @Input() operators: OperatorListButtonGroups = [ - // default operator set - {name: 'Mixed', list: OperatorListComponent.DEFAULT_MIXED_OPERATOR_DIALOGS}, - {name: 'Plots', list: OperatorListComponent.DEFAULT_PLOT_OPERATOR_DIALOGS}, - {name: 'Raster', list: OperatorListComponent.DEFAULT_RASTER_OPERATOR_DIALOGS}, - {name: 'Vector', list: OperatorListComponent.DEFAULT_VECTOR_OPERATOR_DIALOGS}, - ]; - - operatorGroups$: Observable}>>; - searchString$ = new BehaviorSubject(''); - - /** - * DI of services - */ - constructor(private layoutService: LayoutService) {} - - ngOnInit() { - this.operatorGroups$ = combineLatest([of(this.operators), this.searchString$.pipe(map((s) => s.toLowerCase()))]).pipe( - map(([operatorGroups, searchString]) => { - const nameComparator = (a: string, b: string): number => { - const stripped = (s: string): string => s.replace(' ', ''); - - return stripped(a).localeCompare(stripped(b)); - }; - - const filteredGroups = []; - for (const group of operatorGroups) { - const operators = []; - for (const operator of group.list) { - const searchMatchesTypeName = () => operator.type.NAME.toLowerCase().includes(searchString); - const searchMatchesDescription = () => operator.description.toLowerCase().includes(searchString); - - if (searchMatchesTypeName() || searchMatchesDescription()) { - operators.push(operator); - } - } - - if (operators.length > 0) { - filteredGroups.push({ - name: group.name, - list: operators.sort((a, b) => nameComparator(a.type.NAME, b.type.NAME)), - }); - } - } - - return filteredGroups.sort((a, b) => nameComparator(a.name, b.name)); - }), - ); - } - - /** - * Load a selected dialog into the sidenav - */ - load(component: Type) { - this.layoutService.setSidenavContentComponent({component, keepParent: true}); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/pie-chart-operator/pie-chart-operator.component.html b/projects/wave-core/src/lib/operators/dialogs/pie-chart-operator/pie-chart-operator.component.html deleted file mode 100644 index 331f8f42..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/pie-chart-operator/pie-chart-operator.component.html +++ /dev/null @@ -1,32 +0,0 @@ -Pie chart plot -
    -
    - -
    - - - - - {{ attribute }} - - - -
    - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/pie-chart-operator/pie-chart-operator.component.scss b/projects/wave-core/src/lib/operators/dialogs/pie-chart-operator/pie-chart-operator.component.scss deleted file mode 100644 index 07e352ee..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/pie-chart-operator/pie-chart-operator.component.scss +++ /dev/null @@ -1,20 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -mat-form-field { - width: 100%; - margin: 1rem 0; -} - -.actions { - text-align: right; - padding: 1rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/pie-chart-operator/pie-chart-operator.component.ts b/projects/wave-core/src/lib/operators/dialogs/pie-chart-operator/pie-chart-operator.component.ts deleted file mode 100644 index 20144999..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/pie-chart-operator/pie-chart-operator.component.ts +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Created by Julian on 23/06/2017. - */ -import {AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy, OnInit} from '@angular/core'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {ResultTypes} from '../../result-type.model'; -import {Operator} from '../../operator.model'; -import {Plot} from '../../../plots/plot.model'; -import {ProjectService} from '../../../project/project.service'; -import {PieChartType} from '../../types/piechart-type.model'; -import {WaveValidators} from '../../../util/form.validators'; - -@Component({ - selector: 'wave-pie-chart-operator', - templateUrl: './pie-chart-operator.component.html', - styleUrls: ['./pie-chart-operator.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class PieChartComponent implements OnInit, AfterViewInit, OnDestroy { - form: FormGroup; - - ResultTypes = ResultTypes; - - constructor(private formBuilder: FormBuilder, private projectService: ProjectService) {} - - ngOnInit() { - this.form = this.formBuilder.group({ - layer: [undefined, Validators.required], - attribute: [undefined, Validators.required], - name: ['', [Validators.required, WaveValidators.notOnlyWhitespace]], - }); - } - - add(event: any) { - const sourceOperator: Operator = this.form.controls['layer'].value.operator; - - const operator: Operator = new Operator({ - operatorType: new PieChartType({ - attribute: this.form.controls['attribute'].value.toString(), - inputType: sourceOperator.resultType, - }), - resultType: ResultTypes.PLOT, - projection: sourceOperator.projection, - pointSources: sourceOperator.resultType === ResultTypes.POINTS ? [sourceOperator] : undefined, - lineSources: sourceOperator.resultType === ResultTypes.LINES ? [sourceOperator] : undefined, - polygonSources: sourceOperator.resultType === ResultTypes.POLYGONS ? [sourceOperator] : undefined, - }); - - const plot = new Plot({ - name: this.form.controls['name'].value.toString(), - operator: operator, - }); - - this.projectService.addPlot(plot); - } - - ngOnDestroy() {} - - ngAfterViewInit() { - setTimeout(() => { - this.form.updateValueAndValidity({ - onlySelf: false, - emitEvent: true, - }); - this.form.controls['layer'].updateValueAndValidity(); - }); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/point-in-polygon-filter/point-in-polygon-filter.component.html b/projects/wave-core/src/lib/operators/dialogs/point-in-polygon-filter/point-in-polygon-filter.component.html deleted file mode 100644 index 9d251b84..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/point-in-polygon-filter/point-in-polygon-filter.component.html +++ /dev/null @@ -1,15 +0,0 @@ -Point in Polygon Filter -
    -
    - - - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/point-in-polygon-filter/point-in-polygon-filter.component.scss b/projects/wave-core/src/lib/operators/dialogs/point-in-polygon-filter/point-in-polygon-filter.component.scss deleted file mode 100644 index ff2e4bf3..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/point-in-polygon-filter/point-in-polygon-filter.component.scss +++ /dev/null @@ -1,19 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -.actions { - text-align: right; - padding: 1rem; -} - -.error { - color: var(--wave-warn-color, red); -} diff --git a/projects/wave-core/src/lib/operators/dialogs/point-in-polygon-filter/point-in-polygon-filter.component.ts b/projects/wave-core/src/lib/operators/dialogs/point-in-polygon-filter/point-in-polygon-filter.component.ts deleted file mode 100644 index 98164e6e..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/point-in-polygon-filter/point-in-polygon-filter.component.ts +++ /dev/null @@ -1,81 +0,0 @@ -import {Component, ChangeDetectionStrategy} from '@angular/core'; - -import {RandomColorService} from '../../../util/services/random-color.service'; - -import {VectorLayer} from '../../../layers/layer.model'; -import {Operator} from '../../operator.model'; -import {ResultTypes} from '../../result-type.model'; -import {PointInPolygonFilterType} from '../../types/point-in-polygon-filter-type.model'; -import {AbstractVectorSymbology, PointSymbology} from '../../../layers/symbology/symbology.model'; -import {FormGroup, FormBuilder, Validators} from '@angular/forms'; -import {WaveValidators} from '../../../util/form.validators'; -import {ProjectService} from '../../../project/project.service'; - -/** - * This component allows creating the point in polygon filter operator. - */ -@Component({ - selector: 'wave-point-in-polygon-filter', - templateUrl: './point-in-polygon-filter.component.html', - styleUrls: ['./point-in-polygon-filter.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class PointInPolygonFilterOperatorComponent { - ResultTypes = ResultTypes; - - form: FormGroup; - - constructor(private randomColorService: RandomColorService, private projectService: ProjectService, private formBuilder: FormBuilder) { - this.form = formBuilder.group({ - name: ['Filtered Values', [Validators.required, WaveValidators.notOnlyWhitespace]], - pointLayer: [undefined, Validators.required], - polygonLayer: [undefined, Validators.required], - }); - } - - add(event: Event) { - event.preventDefault(); // prevent page reload on error - - if (this.form.invalid) { - return; - } - - // const pointLayer: VectorLayer = this.form.controls['pointLayers'].value[0]; - const pointLayer: VectorLayer = this.form.controls['pointLayer'].value; - const pointOperator: Operator = pointLayer.operator; - const polygonOperator: Operator = this.form.controls['polygonLayer'].value.operator; - - const name: string = this.form.controls['name'].value; - - const operator = new Operator({ - operatorType: new PointInPolygonFilterType({}), - resultType: ResultTypes.POINTS, - projection: pointOperator.projection, - attributes: pointOperator.attributes, - dataTypes: pointOperator.dataTypes, - units: pointOperator.units, - pointSources: [pointOperator], - polygonSources: [polygonOperator], - }); - - const clustered = pointLayer.clustered; - const layer = new VectorLayer({ - name, - operator, - symbology: clustered - ? PointSymbology.createClusterSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }) - : PointSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }), - // data: this.mappingQueryService.getWFSDataStreamAsGeoJsonFeatureCollection({ - // operator, clustered, - // }), - // provenance: this.mappingQueryService.getProvenanceStream(operator), - clustered, - }); - // this.layerService.addLayer(layer); - this.projectService.addLayer(layer); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/r/r-operator/r-operator.component.html b/projects/wave-core/src/lib/operators/dialogs/r/r-operator/r-operator.component.html deleted file mode 100644 index f647ab3b..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/r/r-operator/r-operator.component.html +++ /dev/null @@ -1,165 +0,0 @@ -R Operator -
    -
    - - - - - - - - -

    {{ operator.operatorType }}

    -

    No Input Available

    - -

    {{ operator.operatorType }}

    -

    No Input Available

    - -

    {{ operator.operatorType }}

    -

    No Input Available

    - -

    {{ operator.operatorType }}

    -

    No Input Available

    -
    - - - - - - - help - Quick Help - - How the operator works - - -

    - The R operator allows executing arbitrary R code on VAT data. The result can either be a new - raster or vector layer, a plot or plain text. For accessing the input data there exists a mapping object - that offers the following functionality: -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FunctionalityDescription
    loadRaster(rasterId, queryRectangle) - Load the rasterIdth input raster as an R - raster. -
    loadRasterAsVector(rasterId, queryRectangle)Load the rasterIdth input raster as an R numeric vector.
    rastercountThis variable contains the amount of raster inputs.
    loadPoints(pointId, queryRectangle) - Load the pointIdth input point collection as an R - SpatialPointsDataFrame. -
    pointscountThis variable contains the amount of point collection inputs.
    loadLines(lineId, queryRectangle) - Load the lineIdth input line collection as an R - SpatialLinesDataFrame. -
    linescountThis variable contains the amount of line collection inputs.
    loadPolygons(polygonId, queryRectangle) - Load the polygonIdth input polygon collection as an R - SpatialPolygonDataFrame. -
    polygonscountThis variable contains the amount of polygon collection inputs.
    qrect - This variable is a list that contains the fields - t1, t2, x1, y1, x2, y2, xres, yres and epsg. -
    -

    An example is mapping.loadRaster(0, mapping.qrect) for accessing the first raster.

    -
    -
    - - - -
    - - - -
    - - - - - {{ resultType }} - - - - - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/r/r-operator/r-operator.component.scss b/projects/wave-core/src/lib/operators/dialogs/r/r-operator/r-operator.component.scss deleted file mode 100644 index c5608c30..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/r/r-operator/r-operator.component.scss +++ /dev/null @@ -1,51 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -.actions { - text-align: right; - padding: 1rem; -} - -table { - display: block; - width: 100%; - overflow: auto; -} - -mat-card-content { - text-align: justify; -} - -.load-save { - margin-bottom: 1rem; -} - -mat-form-field { - width: 100%; - margin: 1rem 0; -} - -wave-code-editor { - margin: 1rem 0; -} - -.error { - color: var(--wave-warn-color, red); -} - -mat-panel-title, -mat-panel-description { - line-height: 1.5rem; -} - -mat-panel-title mat-icon { - margin-right: 0.25rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/r/r-operator/r-operator.component.ts b/projects/wave-core/src/lib/operators/dialogs/r/r-operator/r-operator.component.ts deleted file mode 100644 index d03ed38f..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/r/r-operator/r-operator.component.ts +++ /dev/null @@ -1,263 +0,0 @@ -import {first} from 'rxjs/operators'; -import {Component, OnInit, ChangeDetectionStrategy, AfterViewInit, ViewChild, Input} from '@angular/core'; -import {ResultTypes, ResultType} from '../../../result-type.model'; -import {FormGroup, FormBuilder, Validators} from '@angular/forms'; -import {CodeEditorComponent} from '../../../../util/components/code-editor.component'; -import {ProjectService} from '../../../../project/project.service'; -import {DataType} from '../../../datatype.model'; -import {Projections} from '../../../projection.model'; -import {Operator} from '../../../operator.model'; -import {RasterLayer, VectorLayer, Layer} from '../../../../layers/layer.model'; -import {RScriptType} from '../../../types/r-script-type.model'; -import {Unit} from '../../../unit.model'; -import {RandomColorService} from '../../../../util/services/random-color.service'; -import {Plot} from '../../../../plots/plot.model'; -import { - AbstractRasterSymbology, - AbstractVectorSymbology, - AbstractSymbology, - PointSymbology, - MappingRasterSymbology, -} from '../../../../layers/symbology/symbology.model'; -import {MatDialog} from '@angular/material/dialog'; -import {RScriptSaveComponent, RScriptSaveComponentConfig} from '../r-script-save/r-script-save.component'; -import {RScriptLoadComponent, RScriptLoadResult} from '../r-script-load/r-script-load.component'; -import {Config} from '../../../../config.service'; -import {WaveValidators} from '../../../../util/form.validators'; - -@Component({ - selector: 'wave-r-operator', - templateUrl: './r-operator.component.html', - styleUrls: ['./r-operator.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ROperatorComponent implements OnInit, AfterViewInit { - // make available - ResultTypes = ResultTypes; - // - - @ViewChild(CodeEditorComponent, {static: true}) codeEditor: CodeEditorComponent; - - form: FormGroup; - - @Input() editable: Layer | Plot = undefined; - editableSourceLines: Array = undefined; - editableSourcePoints: Array = undefined; - editableSourcePolygons: Array = undefined; - editableSourceRasters: Array = undefined; - - outputTypes: Array; - - constructor( - private formBuilder: FormBuilder, - private projectService: ProjectService, - private randomColorService: RandomColorService, - private dialog: MatDialog, - private config: Config, - ) {} - - ngOnInit() { - if (this.config.DEBUG_MODE.WAVE) { - this.outputTypes = [ResultTypes.POINTS, ResultTypes.PLOT, ResultTypes.RASTER, ResultTypes.TEXT]; - } else { - this.outputTypes = [ResultTypes.PLOT, ResultTypes.TEXT]; - } - - this.form = this.formBuilder.group({ - lineLayers: [[]], - polygonLayers: [[]], - rasterLayers: [[]], - pointLayers: [[]], - code: [`print("Hello world");\na <- 1:5;\nprint(a);`, Validators.required], - resultType: [ResultTypes.TEXT, Validators.required], - name: ['R Output', [Validators.required, WaveValidators.notOnlyWhitespace]], - }); - - if (this.editable) { - // edit existing operator - - let name: string; - let operatorType: RScriptType; - let resultType: ResultType; - let rasterOperators: Array; - let pointOperators: Array; - let lineOperators: Array; - let polygonOperators: Array; - - if (this.editable instanceof VectorLayer) { - const vectorLayer: VectorLayer = this.editable; - name = vectorLayer.name; - resultType = vectorLayer.operator.resultType; - rasterOperators = vectorLayer.operator.getSources(ResultTypes.RASTER).toArray(); - pointOperators = vectorLayer.operator.getSources(ResultTypes.POINTS).toArray(); - lineOperators = vectorLayer.operator.getSources(ResultTypes.LINES).toArray(); - polygonOperators = vectorLayer.operator.getSources(ResultTypes.POLYGONS).toArray(); - operatorType = vectorLayer.operator.operatorType as RScriptType; - } else if (this.editable instanceof RasterLayer) { - const rasterLayer: RasterLayer = this.editable as RasterLayer; - name = rasterLayer.name; - resultType = rasterLayer.operator.resultType; - rasterOperators = rasterLayer.operator.getSources(ResultTypes.RASTER).toArray(); - pointOperators = rasterLayer.operator.getSources(ResultTypes.POINTS).toArray(); - lineOperators = rasterLayer.operator.getSources(ResultTypes.LINES).toArray(); - polygonOperators = rasterLayer.operator.getSources(ResultTypes.POLYGONS).toArray(); - operatorType = rasterLayer.operator.operatorType as RScriptType; - } else if (this.editable instanceof Plot) { - const plot: Plot = this.editable; - name = plot.name; - resultType = plot.operator.resultType; - rasterOperators = plot.operator.getSources(ResultTypes.RASTER).toArray(); - pointOperators = plot.operator.getSources(ResultTypes.POINTS).toArray(); - lineOperators = plot.operator.getSources(ResultTypes.LINES).toArray(); - polygonOperators = plot.operator.getSources(ResultTypes.POLYGONS).toArray(); - operatorType = plot.operator.operatorType as RScriptType; - } else { - throw Error('unknown type to edit'); - } - - this.form.controls['name'].setValue(name); - this.form.controls['resultType'].setValue(resultType); - this.form.controls['code'].setValue(operatorType.toDict().code); - - // this.form.controls['rasterLayers'].setValue(rasterLayers); - // this.form.controls['pointLayers'].setValue(pointLayers); - this.editableSourceRasters = rasterOperators; - this.editableSourcePoints = pointOperators; - this.editableSourceLines = lineOperators; - this.editableSourcePolygons = polygonOperators; - } - } - - ngAfterViewInit() { - setTimeout(() => { - this.form.updateValueAndValidity(); - this.codeEditor.refresh(); - }); - } - - load() { - this.dialog - .open(RScriptLoadComponent) - .afterClosed() - .pipe(first()) - .subscribe((result: RScriptLoadResult) => { - if (result) { - this.form.controls['code'].setValue(result.script.code); - this.form.controls['resultType'].setValue(result.script.resultType); - } - }); - } - - save() { - this.dialog.open(RScriptSaveComponent, { - data: { - script: { - code: this.form.controls['code'].value, - resultType: this.form.controls['resultType'].value, - }, - } as RScriptSaveComponentConfig, - }); - } - - add(event: any) { - const rasterLayers: Array> = this.form.controls['rasterLayers'].value; - const pointLayers: Array> = this.form.controls['pointLayers'].value; - const lineLayers: Array> = this.form.controls['lineLayers'].value; - const polygonLayers: Array> = this.form.controls['polygonLayers'].value; - - const getAnySource = (index: number) => { - const allSources = [...rasterLayers, ...pointLayers, ...lineLayers, ...polygonLayers]; - return allSources[index]; - }; - - const outputName: string = this.form.controls['name'].value; - const resultType: DataType = this.form.controls['resultType'].value; - const code = this.form.controls['code'].value; - - // TODO: user input? - const projection = getAnySource(0) === undefined ? Projections.WGS_84 : getAnySource(0).operator.projection; - - let rasterSources: Array; - let pointSources: Array; - let lineSources: Array; - let polygonSources: Array; - - if (this.editable) { - rasterSources = this.editableSourceRasters.map((o) => o.getProjectedOperator(projection)); - pointSources = this.editableSourcePoints.map((o) => o.getProjectedOperator(projection)); - lineSources = this.editableSourceLines.map((o) => o.getProjectedOperator(projection)); - polygonSources = this.editableSourcePolygons.map((o) => o.getProjectedOperator(projection)); - } else { - rasterSources = rasterLayers.map((layer) => layer.operator.getProjectedOperator(projection)); - pointSources = pointLayers.map((layer) => layer.operator.getProjectedOperator(projection)); - lineSources = lineLayers.map((layer) => layer.operator.getProjectedOperator(projection)); - polygonSources = polygonLayers.map((layer) => layer.operator.getProjectedOperator(projection)); - } - - const operator = new Operator({ - operatorType: new RScriptType({ - code, - resultType, - }), - resultType, - projection, - attributes: [], // TODO: user input? - dataTypes: new Map(), // TODO: user input? - units: new Map(), // TODO: user input? - rasterSources, - pointSources, - lineSources, - polygonSources, - }); - - if (ResultTypes.LAYER_TYPES.indexOf(resultType) >= 0) { - // LAYER - let layer: Layer; - switch (resultType) { - case ResultTypes.POINTS: - layer = new VectorLayer({ - name: outputName, - operator, - symbology: PointSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }), - // data: this.mappingQueryService.getWFSDataStreamAsGeoJsonFeatureCollection({ - // operator, - // }), - // provenance: provenance$, - }); - break; - case ResultTypes.RASTER: - layer = new RasterLayer({ - name: outputName, - operator, - // TODO: read out of operator if specified - symbology: MappingRasterSymbology.createSymbology({unit: Unit.defaultUnit}), - // provenance: provenance$, - }); - break; - default: - throw Error('Unknown AbstractSymbology Error'); - } - - if (this.editable) { - // TODO: implement replace functionality - this.projectService.addLayer(layer); - } else { - this.projectService.addLayer(layer); - } - } else { - // PLOT - const plot = new Plot({ - name: outputName, - operator, - }); - - if (this.editable) { - this.projectService.replacePlot(this.editable as Plot, plot); - } else { - this.projectService.addPlot(plot); - } - } - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/r/r-script-load/r-script-load.component.html b/projects/wave-core/src/lib/operators/dialogs/r/r-script-load/r-script-load.component.html deleted file mode 100644 index 01d42983..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/r/r-script-load/r-script-load.component.html +++ /dev/null @@ -1,10 +0,0 @@ -Load R Script -
    - - - {{ name }} - - - -
    - diff --git a/projects/wave-core/src/lib/operators/dialogs/r/r-script-load/r-script-load.component.scss b/projects/wave-core/src/lib/operators/dialogs/r/r-script-load/r-script-load.component.scss deleted file mode 100644 index c8400b3d..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/r/r-script-load/r-script-load.component.scss +++ /dev/null @@ -1,15 +0,0 @@ -mat-radio-group, -mat-radio-button, -button { - width: 100%; -} - -button { - margin-top: 1rem; -} - -mat-progress-spinner { - width: 50%; - height: auto; - margin: 0 auto; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/r/r-script-load/r-script-load.component.ts b/projects/wave-core/src/lib/operators/dialogs/r/r-script-load/r-script-load.component.ts deleted file mode 100644 index d05b5484..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/r/r-script-load/r-script-load.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy, AfterViewInit} from '@angular/core'; -import {BehaviorSubject, ReplaySubject} from 'rxjs'; -import {FormBuilder, Validators, FormGroup} from '@angular/forms'; -import {StorageService} from '../../../../storage/storage.service'; -import {MatDialogRef} from '@angular/material/dialog'; -import {RScript} from '../../../../storage/storage-provider.model'; -import {NotificationService} from '../../../../notification.service'; - -export interface RScriptLoadResult { - script: RScript; -} - -@Component({ - selector: 'wave-r-script-load', - templateUrl: './r-script-load.component.html', - styleUrls: ['./r-script-load.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class RScriptLoadComponent implements OnInit, AfterViewInit { - form: FormGroup; - - scriptNames$ = new ReplaySubject>(1); - loading$ = new BehaviorSubject(true); - - constructor( - private storageService: StorageService, - private formBuilder: FormBuilder, - private dialogRef: MatDialogRef, - private notificationService: NotificationService, - ) {} - - ngOnInit() { - this.form = this.formBuilder.group({ - scriptName: [undefined, Validators.required], - }); - - this.storageService.getRScripts().subscribe((scripts) => { - this.scriptNames$.next(scripts); - this.loading$.next(false); - }); - } - - ngAfterViewInit() { - setTimeout(() => this.form.updateValueAndValidity()); - } - - load() { - this.loading$.next(true); - - const scriptName: string = this.form.controls['scriptName'].value; - this.storageService.loadRScriptByName(scriptName).subscribe((script) => { - this.loading$.next(false); - this.notificationService.info(`Loaded R script »${scriptName}«`); - this.dialogRef.close({script: script} as RScriptLoadResult); - }); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/r/r-script-save/r-script-save.component.html b/projects/wave-core/src/lib/operators/dialogs/r/r-script-save/r-script-save.component.html deleted file mode 100644 index d4b913a8..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/r/r-script-save/r-script-save.component.html +++ /dev/null @@ -1,11 +0,0 @@ -Save R Script -
    - - - - The name must be non-empty. - - - -
    - diff --git a/projects/wave-core/src/lib/operators/dialogs/r/r-script-save/r-script-save.component.scss b/projects/wave-core/src/lib/operators/dialogs/r/r-script-save/r-script-save.component.scss deleted file mode 100644 index d3cb4cb0..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/r/r-script-save/r-script-save.component.scss +++ /dev/null @@ -1,19 +0,0 @@ -mat-form-field, -input, -button { - width: 100%; -} - -button { - margin-top: 1rem; -} - -.error { - color: var(--wave-warn-color, red); -} - -mat-progress-spinner { - width: 50%; - height: auto; - margin: 0 auto; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/r/r-script-save/r-script-save.component.ts b/projects/wave-core/src/lib/operators/dialogs/r/r-script-save/r-script-save.component.ts deleted file mode 100644 index 21e64925..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/r/r-script-save/r-script-save.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy, AfterViewInit, Inject} from '@angular/core'; -import {FormGroup, FormBuilder, Validators} from '@angular/forms'; -import {StorageService} from '../../../../storage/storage.service'; -import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog'; -import {RScript} from '../../../../storage/storage-provider.model'; -import {BehaviorSubject} from 'rxjs'; -import {NotificationService} from '../../../../notification.service'; -import {WaveValidators} from '../../../../util/form.validators'; - -export interface RScriptSaveComponentConfig { - script: RScript; -} - -@Component({ - selector: 'wave-r-script-save', - templateUrl: './r-script-save.component.html', - styleUrls: ['./r-script-save.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class RScriptSaveComponent implements OnInit, AfterViewInit { - form: FormGroup; - - loading$ = new BehaviorSubject(false); - - constructor( - private storageService: StorageService, - private formBuilder: FormBuilder, - private dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) private config: RScriptSaveComponentConfig, - private notificationService: NotificationService, - ) {} - - ngOnInit() { - this.form = this.formBuilder.group({ - name: ['', [Validators.required, WaveValidators.notOnlyWhitespace]], - script: [this.config.script, Validators.required], - }); - } - - ngAfterViewInit() { - setTimeout(() => this.form.updateValueAndValidity()); - } - - save() { - this.loading$.next(true); - - const scriptName: string = this.form.controls['name'].value; - const script: RScript = this.form.controls['script'].value; - - this.storageService.saveRScript(scriptName, script).subscribe(() => { - this.loading$.next(false); - this.notificationService.info(`Stored R script »${scriptName}«`); - this.dialogRef.close(); - }); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/raster-mask/raster-mask.component.html b/projects/wave-core/src/lib/operators/dialogs/raster-mask/raster-mask.component.html deleted file mode 100644 index 96a21ddd..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/raster-mask/raster-mask.component.html +++ /dev/null @@ -1,26 +0,0 @@ -Raster Mask - - - The Raster Mask modifies an input raster layer by applying another raster layer as a mask . The mask layer should contain either - zeros and ones or NO DATA and ones. The resulting layer contains its original values at all positions that are neither zero nor NO DATA. - - -
    -
    - - - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/raster-mask/raster-mask.component.scss b/projects/wave-core/src/lib/operators/dialogs/raster-mask/raster-mask.component.scss deleted file mode 100644 index 79df5eae..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/raster-mask/raster-mask.component.scss +++ /dev/null @@ -1,16 +0,0 @@ -:host { - display: block; - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.actions { - text-align: right; - padding: 1rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/raster-mask/raster-mask.component.ts b/projects/wave-core/src/lib/operators/dialogs/raster-mask/raster-mask.component.ts deleted file mode 100644 index dd93f801..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/raster-mask/raster-mask.component.ts +++ /dev/null @@ -1,72 +0,0 @@ -import {Component, ChangeDetectionStrategy} from '@angular/core'; -import {ResultTypes} from '../../result-type.model'; -import {FormControl, FormGroup, Validators} from '@angular/forms'; -import {combineLatest, Observable} from 'rxjs'; -import {map} from 'rxjs/operators'; -import {ProjectService} from '../../../project/project.service'; -import {Layer, RasterLayer} from '../../../layers/layer.model'; -import {AbstractSymbology, AbstractRasterSymbology} from '../../../layers/symbology/symbology.model'; -import {Operator} from '../../operator.model'; -import {ExpressionType} from '../../types/expression-type.model'; - -@Component({ - selector: 'wave-raster-mask', - templateUrl: './raster-mask.component.html', - styleUrls: ['./raster-mask.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class RasterMaskComponent { - readonly RASTER_TYPE = [ResultTypes.RASTER]; - - form: FormGroup; - formIsInvalid$: Observable; - availableMaskLayers$: Observable>>; - - constructor(private projectService: ProjectService) { - this.form = new FormGroup({ - input: new FormControl(undefined, [Validators.required]), - mask: new FormControl(undefined, [Validators.required]), - name: new FormControl('Masked Layer', [Validators.required]), - }); - - this.formIsInvalid$ = this.form.statusChanges.pipe(map((status) => status !== 'VALID')); - - this.availableMaskLayers$ = combineLatest([this.form.controls.input.valueChanges, this.projectService.getLayerStream()]).pipe( - map(([selectedLayer, list]: [Layer, Array>]) => { - return list.filter((layer) => layer !== selectedLayer); - }), - ); - - setTimeout(() => { - // calculate validity to enforce invalid state upfront - this.form.controls.input.updateValueAndValidity({emitEvent: true}); - this.form.updateValueAndValidity(); - }); - } - - add() { - const inputLayer: RasterLayer = this.form.controls.input.value; - const maskLayer: RasterLayer = this.form.controls.mask.value; - const name = this.form.controls.name.value as string; - - this.projectService.addLayer( - new RasterLayer({ - name, - operator: new Operator({ - attributes: inputLayer.operator.attributes, - dataTypes: inputLayer.operator.dataTypes, - operatorType: new ExpressionType({ - datatype: inputLayer.operator.dataTypes.get('value'), - expression: 'B != 0 ? A : out_info->no_data', - unit: inputLayer.operator.units.get('value'), - }), - projection: inputLayer.operator.projection, - rasterSources: [inputLayer.operator, maskLayer.operator], - resultType: inputLayer.operator.resultType, - units: inputLayer.operator.units, - }), - symbology: inputLayer.symbology, - }), - ); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/raster-polygon-clip/raster-polygon-clip.component.html b/projects/wave-core/src/lib/operators/dialogs/raster-polygon-clip/raster-polygon-clip.component.html deleted file mode 100644 index af8ade87..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/raster-polygon-clip/raster-polygon-clip.component.html +++ /dev/null @@ -1,15 +0,0 @@ -Raster Polygon Clip -
    -
    - - - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/raster-polygon-clip/raster-polygon-clip.component.scss b/projects/wave-core/src/lib/operators/dialogs/raster-polygon-clip/raster-polygon-clip.component.scss deleted file mode 100644 index ff2e4bf3..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/raster-polygon-clip/raster-polygon-clip.component.scss +++ /dev/null @@ -1,19 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -.actions { - text-align: right; - padding: 1rem; -} - -.error { - color: var(--wave-warn-color, red); -} diff --git a/projects/wave-core/src/lib/operators/dialogs/raster-polygon-clip/raster-polygon-clip.component.ts b/projects/wave-core/src/lib/operators/dialogs/raster-polygon-clip/raster-polygon-clip.component.ts deleted file mode 100644 index 51e91cd8..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/raster-polygon-clip/raster-polygon-clip.component.ts +++ /dev/null @@ -1,84 +0,0 @@ -import {ChangeDetectionStrategy, Component, OnInit} from '@angular/core'; - -import {RandomColorService} from '../../../util/services/random-color.service'; - -import {RasterLayer} from '../../../layers/layer.model'; -import {Operator} from '../../operator.model'; -import {ResultTypes} from '../../result-type.model'; -import {AbstractRasterSymbology} from '../../../layers/symbology/symbology.model'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {WaveValidators} from '../../../util/form.validators'; -import {ProjectService} from '../../../project/project.service'; -import {ExpressionType} from '../../types/expression-type.model'; -import {RasterizePolygonType} from '../../types/rasterize-polygon-type.model'; - -/** - * This component allows composing the raster polygon clip operator. - */ -@Component({ - selector: 'wave-raster-polygon-clip', - templateUrl: './raster-polygon-clip.component.html', - styleUrls: ['./raster-polygon-clip.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class RasterPolygonClipOperatorComponent implements OnInit { - ResultTypes = ResultTypes; - - form: FormGroup; - - constructor(private randomColorService: RandomColorService, private projectService: ProjectService, private formBuilder: FormBuilder) { - this.form = formBuilder.group({ - name: ['Clipped Raster', [Validators.required, WaveValidators.notOnlyWhitespace]], - rasterLayer: [undefined, Validators.required], - polygonLayer: [undefined, Validators.required], - }); - } - - ngOnInit(): void { - setTimeout(() => this.form.updateValueAndValidity({emitEvent: true})); - } - - add() { - if (this.form.invalid) { - return; - } - - const rasterLayer: RasterLayer = this.form.controls['rasterLayer'].value; - const rasterOperator: Operator = rasterLayer.operator; - const polygonOperator: Operator = this.form.controls['polygonLayer'].value.operator; - - const name: string = this.form.controls['name'].value; - - const rasterizePolygonOperator = new Operator({ - operatorType: new RasterizePolygonType({}), - resultType: ResultTypes.RASTER, - projection: rasterOperator.projection, - attributes: rasterOperator.attributes, - dataTypes: rasterOperator.dataTypes, - units: rasterOperator.units, - polygonSources: [polygonOperator], - }); - - const expressionOperator = new Operator({ - operatorType: new ExpressionType({ - expression: `B > 0 ? A : NAN`, - datatype: rasterOperator.getDataType('value'), - unit: rasterOperator.getUnit('value'), - }), - resultType: ResultTypes.RASTER, - projection: rasterOperator.projection, - attributes: rasterOperator.attributes, - dataTypes: rasterOperator.dataTypes, - units: rasterOperator.units, - rasterSources: [rasterOperator, rasterizePolygonOperator], - }); - - const layer = new RasterLayer({ - name, - operator: expressionOperator, - symbology: rasterLayer.symbology, - }); - - this.projectService.addLayer(layer); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/raster-value-extraction/raster-value-extraction.component.html b/projects/wave-core/src/lib/operators/dialogs/raster-value-extraction/raster-value-extraction.component.html deleted file mode 100644 index cfe6bfcc..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/raster-value-extraction/raster-value-extraction.component.html +++ /dev/null @@ -1,34 +0,0 @@ -Extract a Raster Value and Add it to the Vector Layer -
    -
    - - - -
    - - - - Duplicate Value - - -
    - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/raster-value-extraction/raster-value-extraction.component.scss b/projects/wave-core/src/lib/operators/dialogs/raster-value-extraction/raster-value-extraction.component.scss deleted file mode 100644 index 902d0327..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/raster-value-extraction/raster-value-extraction.component.scss +++ /dev/null @@ -1,24 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -.actions { - text-align: right; - padding: 1rem; -} - -div { - padding-bottom: 0.5rem; - padding-top: 1rem; -} - -.error { - color: var(--wave-warn-color, red); -} diff --git a/projects/wave-core/src/lib/operators/dialogs/raster-value-extraction/raster-value-extraction.component.ts b/projects/wave-core/src/lib/operators/dialogs/raster-value-extraction/raster-value-extraction.component.ts deleted file mode 100644 index b5deb50e..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/raster-value-extraction/raster-value-extraction.component.ts +++ /dev/null @@ -1,242 +0,0 @@ -import {ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy} from '@angular/core'; -import {ResultTypes} from '../../result-type.model'; -import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms'; -import {RandomColorService} from '../../../util/services/random-color.service'; -import {LetterNumberConverter} from '../helpers/multi-layer-selection/multi-layer-selection.component'; -import {Subscription} from 'rxjs'; -import {VectorLayer} from '../../../layers/layer.model'; -import {AbstractVectorSymbology, PointSymbology, VectorSymbology} from '../../../layers/symbology/symbology.model'; -import {Operator} from '../../operator.model'; -import {RasterValueExtractionType} from '../../types/raster-value-extraction-type.model'; -import {WaveValidators} from '../../../util/form.validators'; -import {ProjectService} from '../../../project/project.service'; - -/** - * Checks for collisions of value name. - * Uses `startsWith` semantics. - */ -function valueNameCollision(vectorLayerControl: FormControl, valueNames: FormArray) { - return (control: FormControl): {[key: string]: boolean} => { - const errors: { - duplicateName?: boolean; - } = {}; - - const valueName: string = control.value; - - let duplicates = 0; - - for (const otherValueName of valueNames.value as Array) { - if (otherValueName.startsWith(valueName)) { - duplicates++; - } - } - - if (duplicates < 2) { - const vectorLayer: VectorLayer = vectorLayerControl.value; - if (vectorLayer) { - for (const otherValueName of vectorLayer.operator.attributes.toArray()) { - if (otherValueName.startsWith(valueName)) { - duplicates++; - } - } - } - } - - if (duplicates > 1) { - errors.duplicateName = true; - } - - return Object.keys(errors).length > 0 ? errors : null; - }; -} - -@Component({ - selector: 'wave-raster-value-extraction', - templateUrl: './raster-value-extraction.component.html', - styleUrls: ['./raster-value-extraction.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class RasterValueExtractionOperatorComponent implements OnDestroy { - // make accessible - ResultTypes = ResultTypes; - LetterNumberConverter = LetterNumberConverter; - // - - form: FormGroup; - - private valueNameChanges: Array = []; - - private subscriptions: Array = []; - - constructor( - private projectService: ProjectService, - private randomColorService: RandomColorService, - private formBuilder: FormBuilder, - private changeDetectorRef: ChangeDetectorRef, - ) { - this.form = this.formBuilder.group({ - vectorLayer: [undefined, Validators.required], - rasterLayers: [undefined, Validators.required], - valueNames: this.formBuilder.array([]), - name: ['Vectors With Raster Values', [Validators.required, WaveValidators.notOnlyWhitespace]], - }); - - this.subscriptions.push( - // update valueNames - this.form.controls['rasterLayers'].valueChanges.subscribe((rasters) => { - const valueNames = this.form.controls['valueNames'] as FormArray; - - if (valueNames.length > rasters.length) { - // remove name fields - for (let i = rasters.length; i < valueNames.length; i++) { - valueNames.removeAt(i); - this.valueNameChanges.splice(i, 1); - } - } else if (valueNames.length < rasters.length) { - // add name fields - for (let i = valueNames.length; i < rasters.length; i++) { - const control = this.formBuilder.control( - rasters[i].name, - Validators.compose([ - Validators.required, - valueNameCollision( - this.form.controls['vectorLayer'] as FormControl, - this.form.controls['valueNames'] as FormArray, - ), - ]), - ); - valueNames.push(control); - this.valueNameChanges.push(false); - - this.subscriptions.push( - control.valueChanges.subscribe((valueName) => { - // const rasterName = this.form.controls['rasterLayers'].value[i].name; - const rasterName = rasters[i].name; - if (valueName !== rasterName) { - this.valueNameChanges[i] = true; - } - - // check validity of other valueName controls - setTimeout( - () => - valueNames.controls.forEach((myControl) => { - myControl.updateValueAndValidity({ - onlySelf: false, - emitEvent: false, - }); - this.changeDetectorRef.markForCheck(); - }), - 0, - ); - }), - ); - } - } else { - // update names if not changed by user - for (let i = 0; i < rasters.length; i++) { - if (!this.valueNameChanges[i]) { - valueNames.at(i).setValue(rasters[i].name); - } - // TODO: change name if other layer is selected - } - } - }), - ); - } - - ngOnDestroy() { - this.subscriptions.forEach((subscription) => subscription.unsubscribe()); - } - - add(event: any) { - const vectorOperator: Operator = this.form.controls['vectorLayer'].value.operator; - const projection = vectorOperator.projection; - const resultType = vectorOperator.resultType; - - const rasterOperators: Array = this.form.controls['rasterLayers'].value.map((inputLayer) => - inputLayer.operator.getProjectedOperator(projection), - ); - - const valueNames: Array = this.form.controls['valueNames'].value; - - // ATTENTION: make the three mutable copies to loop just once over the rasters - // -> make them immutable to put them into the operator - const units = vectorOperator.units.asMutable(); - const dataTypes = vectorOperator.dataTypes.asMutable(); - const attributes = vectorOperator.attributes.asMutable(); - - const name: string = this.form.controls['name'].value; - - // TODO: magic numbers - const resolutionX = 1024; - const resolutionY = 1024; - - let clustered = false; - let symbology: AbstractVectorSymbology; - - switch (resultType) { - case ResultTypes.POINTS: - clustered = this.form.controls['vectorLayer'].value.clustered; - - symbology = clustered - ? PointSymbology.createClusterSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }) - : PointSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - - for (let i = 0; i < rasterOperators.length; i++) { - units.set(valueNames[i], rasterOperators[i].getUnit('value')); - dataTypes.set(valueNames[i], rasterOperators[i].getDataType('value')); - attributes.push(valueNames[i]); - } - - break; - case ResultTypes.POLYGONS: - symbology = VectorSymbology.createSymbology({ - fillRGBA: this.randomColorService.getRandomColorRgba(), - }); - - for (let i = 0; i < rasterOperators.length; i++) { - for (const valueSuffix of ['mean', 'stdev', 'min', 'max']) { - const attributeName = `${valueNames[i]}_${valueSuffix}`; - - units.set(attributeName, rasterOperators[i].getUnit('value')); - dataTypes.set(attributeName, rasterOperators[i].getDataType('value')); - attributes.push(attributeName); - } - } - - break; - default: - throw Error('Unsupported result type for raster_value_extraction operator'); - } - - const operator = new Operator({ - operatorType: new RasterValueExtractionType({ - xResolution: resolutionX, - yResolution: resolutionY, - attributeNames: valueNames, - }), - resultType, - projection, - attributes: attributes.asImmutable(), // immutable! - dataTypes: dataTypes.asImmutable(), // immutable! - units: units.asImmutable(), // immutable! - pointSources: resultType === ResultTypes.POINTS ? [vectorOperator] : undefined, - lineSources: resultType === ResultTypes.LINES ? [vectorOperator] : undefined, - polygonSources: resultType === ResultTypes.POLYGONS ? [vectorOperator] : undefined, - rasterSources: rasterOperators, - }); - - const layer = new VectorLayer({ - name, - operator, - symbology, - clustered, - }); - - this.projectService.addLayer(layer); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/rgb-composite/rgb-composite.component.html b/projects/wave-core/src/lib/operators/dialogs/rgb-composite/rgb-composite.component.html deleted file mode 100644 index c0ccb3ea..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/rgb-composite/rgb-composite.component.html +++ /dev/null @@ -1,82 +0,0 @@ -Create RGB Composite - - -

    - A RGB Composite, which is, for instance, the data product of any conventional digital camera, is a combination of three - channels in the visual light spectrum: red, green and blue. This operator allows to combine three channels (Input A, B and C) and - calculates a new RGB image based on the channel selection. The min/max values can be derived in two different ways: (1.) - calculate them on the basis of the channels' raster values or (2.) based on the image metadata. After setting the min/max values, - click the Create button. An additional option for this operator is to weight the influence of the channels on the resulting - RGB image by changing the Scaling Factor. -

    -

    - Note: Pay attention to the channel description given by the data provider to select the correct bands for the red, green and blue - channel, respectively. -

    -
    - -
    -
    - - -
    - - - - -

    Red Channel (A)

    -
    - - - - - - - - - -
    -

    Green Channel (B)

    -
    - - - - - - - - - -
    -

    Blue Channel (C)

    -
    - - - - - - - - - -
    -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/rgb-composite/rgb-composite.component.scss b/projects/wave-core/src/lib/operators/dialogs/rgb-composite/rgb-composite.component.scss deleted file mode 100644 index 5365a72f..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/rgb-composite/rgb-composite.component.scss +++ /dev/null @@ -1,28 +0,0 @@ -:host { - display: block; - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { -} - -.container div mat-form-field:not(:last-child) { - margin-right: 1rem; -} - -.container button, -.container mat-spinner { - margin-bottom: 1rem; -} - -.actions { - text-align: right; - padding: 1rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/rgb-composite/rgb-composite.component.ts b/projects/wave-core/src/lib/operators/dialogs/rgb-composite/rgb-composite.component.ts deleted file mode 100644 index d3f916ec..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/rgb-composite/rgb-composite.component.ts +++ /dev/null @@ -1,250 +0,0 @@ -import {ChangeDetectionStrategy, Component, OnDestroy, OnInit} from '@angular/core'; -import {FormControl, FormGroup, Validators} from '@angular/forms'; -import {ResultTypes} from '../../result-type.model'; -import {ProjectService} from '../../../project/project.service'; -import {Layer, RasterLayer} from '../../../layers/layer.model'; -import {MappingRasterSymbology, AbstractRasterSymbology, AbstractSymbology} from '../../../layers/symbology/symbology.model'; -import {Interpolation, Unit} from '../../unit.model'; -import {Operator} from '../../operator.model'; -import {NotificationService} from '../../../notification.service'; -import {DataType, DataTypes} from '../../datatype.model'; -import {ColorizerData} from '../../../colors/colorizer-data.model'; -import {ColorBreakpoint} from '../../../colors/color-breakpoint.model'; -import {RgbaCompositeType} from '../../types/rgba-composite-type.model'; -import {BehaviorSubject, Observable, Subscription} from 'rxjs'; -import {MappingQueryService} from '../../../queries/mapping-query.service'; -import {first, map} from 'rxjs/operators'; -import {StatisticsType} from '../../types/statistics-type.model'; -import {LayoutService} from '../../../layout.service'; -import {WaveValidators} from '../../../util/form.validators'; - -/** - * This dialog allows users to create an RGB composite out of multiple raster layers. - */ -@Component({ - selector: 'wave-create-rgb-composite', - templateUrl: './rgb-composite.component.html', - styleUrls: ['./rgb-composite.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class RgbCompositeComponent implements OnInit, OnDestroy { - readonly inputTypes = [ResultTypes.RASTER]; - readonly numberOfRasters = 3; - readonly loadingSpinnerDiameter = 2 * LayoutService.remInPx; - - form: FormGroup; - formIsInvalid$: Observable; - notAllLayersSet$: Observable; - isRasterStatsLoading$ = new BehaviorSubject(false); - - private inputLayersubscriptions: Subscription; - - /** - * DI for several dependent services - */ - constructor( - private projectService: ProjectService, - private notificationService: NotificationService, - private mappingQueryService: MappingQueryService, - ) {} - - ngOnInit() { - this.form = new FormGroup({ - inputLayers: new FormControl(undefined, [ - Validators.required, - Validators.minLength(this.numberOfRasters), - Validators.maxLength(this.numberOfRasters), - ]), - redMin: new FormControl(undefined, [WaveValidators.isNumber]), - redMax: new FormControl(undefined, [WaveValidators.isNumber]), - redScale: new FormControl(1, [WaveValidators.isNumber, Validators.min(0), Validators.max(1)]), - greenMin: new FormControl(undefined, [WaveValidators.isNumber]), - greenMax: new FormControl(undefined, [WaveValidators.isNumber]), - greenScale: new FormControl(1, [WaveValidators.isNumber, Validators.min(0), Validators.max(1)]), - blueMin: new FormControl(undefined, [WaveValidators.isNumber]), - blueMax: new FormControl(undefined, [WaveValidators.isNumber]), - blueScale: new FormControl(1, [WaveValidators.isNumber, Validators.min(0), Validators.max(1)]), - }); - - this.formIsInvalid$ = this.form.statusChanges.pipe(map((status) => status !== 'VALID')); - this.notAllLayersSet$ = this.form.controls['inputLayers'].valueChanges.pipe( - map((value: Array>) => { - return ( - value === undefined || - value === null || - value.length !== 3 || - value.some((layer) => layer === undefined || layer === null) - ); - }), - ); - - this.inputLayersubscriptions = this.form.controls['inputLayers'].valueChanges.subscribe( - (inputLayers: Array>) => { - // set meaningful default values if possible - const colors = ['red', 'green', 'blue']; - inputLayers.forEach((inputRaster, i) => { - if (inputRaster && !this.form.controls[`${colors[i]}Min`].value) { - this.form.controls[`${colors[i]}Min`].setValue(inputLayers[i].operator.getDataType('value').getMin()); - } - if (inputRaster && !this.form.controls[`${colors[i]}Max`].value) { - this.form.controls[`${colors[i]}Max`].setValue(inputLayers[i].operator.getDataType('value').getMax()); - } - }); - }, - ); - - setTimeout(() => { - // calculate validity to enforce invalid state upfront - this.form.updateValueAndValidity(); - this.form.controls['inputLayers'].updateValueAndValidity(); - }); - } - - ngOnDestroy() { - if (this.inputLayersubscriptions) { - this.inputLayersubscriptions.unsubscribe(); - } - } - - /** - * Creates an RGB layer out of the user input and adds it to the map - */ - add() { - const inputs: Array> = this.form.controls['inputLayers'].value; - const operators = inputs.map((layer) => layer.operator); - - if (inputs.length !== 3) { - this.notificationService.error('RGBA calculation requires 3 inputs.'); - return; - } - - // in case the operators have different projections, use projection of first one - const projection = operators[0].projection; - for (let i = 1; i < operators.length; ++i) { - operators[i] = operators[i].getProjectedOperator(projection); - } - - const unit = new Unit({ - interpolation: Interpolation.Unknown, - measurement: 'unknown', - unit: 'unknown', - min: 1, - max: 0xffffffff, - }); - - this.projectService.addLayer( - new RasterLayer({ - name: `RGB of (${inputs.map((layer) => layer.name).join(', ')})`, - operator: new Operator({ - operatorType: new RgbaCompositeType({ - rasterRedMin: this.form.controls['redMin'].value, - rasterRedMax: this.form.controls['redMax'].value, - rasterRedScale: this.form.controls['redScale'].value, - rasterGreenMin: this.form.controls['greenMin'].value, - rasterGreenMax: this.form.controls['greenMax'].value, - rasterGreenScale: this.form.controls['greenScale'].value, - rasterBlueMin: this.form.controls['blueMin'].value, - rasterBlueMax: this.form.controls['blueMax'].value, - rasterBlueScale: this.form.controls['blueScale'].value, - }), - projection, - rasterSources: operators, - resultType: ResultTypes.RASTER, - attributes: ['value'], - dataTypes: new Map().set('value', DataTypes.UInt32), - units: new Map().set('value', unit), - }), - symbology: MappingRasterSymbology.createSymbology({ - unit, - colorizer: new ColorizerData({ - breakpoints: [ - new ColorBreakpoint({rgba: {r: 0, g: 0, b: 0, a: 0}, value: 0}), - new ColorBreakpoint({rgba: {r: 255, g: 255, b: 255, a: 255}, value: 0xffffffff}), - ], - type: 'rgba_composite', - }), - }), - }), - ); - } - - /** - * Creates on-the-fly a statistics operator for the raster and pastes the result to the - * min/max input fields of the dialog - */ - calculateRasterStats() { - this.isRasterStatsLoading$.next(true); - - this.projectService - .getTimeStream() - .pipe(first()) - .subscribe((time) => { - const inputs: Array> = this.form.controls['inputLayers'].value; - const operators = inputs.map((layer) => layer.operator); - - const operatorA = operators[0]; - const projection = operatorA.projection; - const operatorB = operators[1].getProjectedOperator(projection); - const operatorC = operators[2].getProjectedOperator(projection); - - const operator = new Operator({ - operatorType: new StatisticsType({ - raster_width: 1024, - raster_height: 1024, - }), - projection, - rasterSources: [operatorA, operatorB, operatorC], - resultType: ResultTypes.PLOT, - }); - - this.mappingQueryService - .getPlotData({ - extent: projection.getExtent(), - operator, - projection, - time, - }) - .subscribe((result) => { - const rasterStatistics = ((result as any) as RasterStatisticsType).data.rasters; - - ['red', 'green', 'blue'].forEach((color, i) => { - this.form.controls[`${color}Min`].setValue(rasterStatistics[i].min); - this.form.controls[`${color}Max`].setValue(rasterStatistics[i].max); - }); - - this.isRasterStatsLoading$.next(false); - }); - }); - } - - /** - * Retrieves the min/max information of the units of the raster layers and - * pastes the result to the min/max input fields of the dialog - */ - retrieveRasterStatsFromUnit() { - const operators: Array = this.form.controls['inputLayers'].value.map((layer) => layer.operator); - - ['red', 'green', 'blue'].forEach((color, i) => { - const unit = operators[i].units.get('value', Unit.defaultUnit); - this.form.controls[`${color}Min`].setValue(unit.min); - this.form.controls[`${color}Max`].setValue(unit.max); - }); - } -} - -/** - * The result type of the raster statistics (plot) operator - * - * The results of tht rasters are returned in the same order of the query - */ -interface RasterStatisticsType { - data: { - rasters: Array<{ - count: number; - max: number; - mean: number; - min: number; - nan_count: number; - }>; - }; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.component.html b/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.component.html deleted file mode 100644 index daf0d165..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.component.html +++ /dev/null @@ -1,55 +0,0 @@ -Scatter plot -
    -
    - -
    - - - - - {{ attribute }} - - - - - - {{ attribute }} - - - - - - Regression line -
    - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.component.scss b/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.component.scss deleted file mode 100644 index 0fc777fd..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.component.scss +++ /dev/null @@ -1,17 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} -mat-form-field { - width: 100%; - margin: 1rem 0; -} -.actions { - text-align: right; - padding: 1rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.component.ts b/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.component.ts deleted file mode 100644 index 853da6fc..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.component.ts +++ /dev/null @@ -1,68 +0,0 @@ -import {AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy, OnInit} from '@angular/core'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {ResultTypes} from '../../result-type.model'; -import {Operator} from '../../operator.model'; -import {Plot} from '../../../plots/plot.model'; -import {ProjectService} from '../../../project/project.service'; -import {DataTypes} from '../../datatype.model'; -import {ScatterPlotType} from '../../types/scatterplot-type.model'; -import {WaveValidators} from '../../../util/form.validators'; - -@Component({ - selector: 'wave-scatter-plot-operator', - templateUrl: './scatter-plot-operator.component.html', - styleUrls: ['./scatter-plot-operator.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ScatterPlotComponent implements OnInit, AfterViewInit, OnDestroy { - form: FormGroup; - ResultTypes = ResultTypes; - DataTypes = DataTypes; - - constructor(private formBuilder: FormBuilder, private projectService: ProjectService) {} - - ngOnInit() { - this.form = this.formBuilder.group({ - vLayer: [undefined, Validators.required], - attribute1: [undefined, Validators.required], - attribute2: [undefined, Validators.required], - isRegression: [false, Validators.required], - name: ['', [Validators.required, WaveValidators.notOnlyWhitespace]], - }); - } - - add(event: any) { - const sourceOperator: Operator = this.form.controls['vLayer'].value.operator; - - const operator: Operator = new Operator({ - operatorType: new ScatterPlotType({ - attribute1: this.form.controls['attribute1'].value.toString(), - attribute2: this.form.controls['attribute2'].value.toString(), - regression: this.form.controls['isRegression'].value, - inputType: sourceOperator.resultType, - }), - resultType: ResultTypes.PLOT, - projection: sourceOperator.projection, - pointSources: sourceOperator.resultType === ResultTypes.POINTS ? [sourceOperator] : undefined, - lineSources: sourceOperator.resultType === ResultTypes.LINES ? [sourceOperator] : undefined, - polygonSources: sourceOperator.resultType === ResultTypes.POLYGONS ? [sourceOperator] : undefined, - }); - const plot = new Plot({ - name: this.form.controls['name'].value, - operator: operator, - }); - this.projectService.addPlot(plot); - } - - ngOnDestroy() {} - - ngAfterViewInit() { - setTimeout(() => { - this.form.updateValueAndValidity({ - onlySelf: false, - emitEvent: true, - }); - this.form.controls['vLayer'].updateValueAndValidity(); - }); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.pipe.ts b/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.pipe.ts deleted file mode 100644 index d9fdce49..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/scatter-plot-operator/scatter-plot-operator.pipe.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {Pipe} from '@angular/core'; -import {DataTypes} from '../../datatype.model'; -import {Operator} from '../../operator.model'; - -@Pipe({ - name: 'NumericPipe', -}) -export class NumericPipe { - transform(value: Array, op: Operator) { - return value.filter((x) => DataTypes.ALL_NUMERICS.indexOf(op.dataTypes.get(x)) >= 0); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/source-operator-list/source-operator-list.component.html b/projects/wave-core/src/lib/operators/dialogs/source-operator-list/source-operator-list.component.html deleted file mode 100644 index c8a3b762..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/source-operator-list/source-operator-list.component.html +++ /dev/null @@ -1,30 +0,0 @@ -Add Data - - -

    - The VAT system supports very different types of data: raster and vector data. Rasters consist of - many pixels, and each pixel contains a value for the particular location, e.g. the mean temperature. Vector data are collections of - features with attributes, e.g., a set of occurrences of pumas and the time of the observation. -

    -

    - In this section, you can select one of several data sources. Each data set is added to the map as a new layer, which you can further - process with operators. -

    -
    - -
    - - - - - {{ button.icon }} -

    {{ button.name }}

    -

    {{ button.description }}

    -
    -
    -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/source-operator-list/source-operator-list.component.scss b/projects/wave-core/src/lib/operators/dialogs/source-operator-list/source-operator-list.component.scss deleted file mode 100644 index d8f1dcb4..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/source-operator-list/source-operator-list.component.scss +++ /dev/null @@ -1,32 +0,0 @@ -:host { - display: block; - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -mat-list-item { - cursor: pointer; -} - -::ng-deep .mat-list-item-content img { - width: 100%; - height: 100%; -} - -::ng-deep .mat-list-item-content p { - color: var(--wave-foreground-secondary-text-color, grey); -} - -.disabled { - ::ng-deep .mat-list-item-content { - cursor: auto; - } - - h4 { - color: var(--wave-foreground-secondary-text-color, grey); - } - - img { - filter: grayscale(100%); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/source-operator-list/source-operator-list.component.ts b/projects/wave-core/src/lib/operators/dialogs/source-operator-list/source-operator-list.component.ts deleted file mode 100644 index 3bdde254..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/source-operator-list/source-operator-list.component.ts +++ /dev/null @@ -1,149 +0,0 @@ -import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit} from '@angular/core'; -import {LayoutService, SidenavConfig} from '../../../layout.service'; -import {DataRepositoryComponent} from '../data-repository/data-repository.component'; -import {RasterSourceType} from '../../types/raster-source-type.model'; -import {CsvSourceType} from '../../types/csv-source-type.model'; -import {FeaturedbSourceListComponent} from '../featuredb-source-list/featuredb-source-list.component'; -import {UserService} from '../../../users/user.service'; -import {Subscription} from 'rxjs'; -import {OlDrawFeaturesComponent} from '../draw-features/ol-draw-features.component'; -import {CountryPolygonSelectionComponent} from '../country-polygon-selection/country-polygon-selection.component'; - -/** - * These settings specify source list buttons. - * - * You can either specify a icon (name) from the icon library or an image source. - * Only `onlyIfLoggedIn` or `onlyIfLoggedOut` should be specified to see the button. - */ -export interface SourceOperatorListButton { - name: string; - description: string; - icon?: string; - iconSrc?: string; - sidenavConfig: SidenavConfig | undefined; - onlyIfLoggedIn?: boolean; - onlyIfLoggedOut?: boolean; -} - -/** - * This component provides a list of data source dialogs to add data. - */ -@Component({ - selector: 'wave-source-operator-list', - templateUrl: './source-operator-list.component.html', - styleUrls: ['./source-operator-list.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class SourceOperatorListComponent implements OnInit, OnDestroy { - /** - * A list of data source dialogs to display - */ - @Input() buttons!: Array; - - public isUserLoggedIn = false; - - private guestUserStreamSubscription: Subscription; - - /** - * DI for services - */ - constructor(private changeDetectorRef: ChangeDetectorRef, private layoutService: LayoutService, private userService: UserService) {} - - ngOnInit() { - this.guestUserStreamSubscription = this.userService.isGuestUserStream().subscribe((isGuest) => { - this.isUserLoggedIn = !isGuest; - this.changeDetectorRef.markForCheck(); - }); - } - - ngOnDestroy() { - if (this.guestUserStreamSubscription) { - this.guestUserStreamSubscription.unsubscribe(); - } - } - - /** - * Checks with respect to the current user and the settings - * whether the component can be displayed to the user - */ - isShowable(onlyIfLoggedIn?: boolean, onlyIfLoggedOut?: boolean): boolean { - if (onlyIfLoggedIn && onlyIfLoggedOut) { - return false; - } else if (onlyIfLoggedIn) { - return this.isUserLoggedIn; - } else if (onlyIfLoggedOut) { - return !this.isUserLoggedIn; - } else { - return true; - } - } - - /** - * Load a selected component into the sidenav - */ - setComponent(sidenavConfig: SidenavConfig) { - if (!sidenavConfig) { - return; - } - - this.layoutService.setSidenavContentComponent(sidenavConfig); - } - - /** - * Default for a data repository entry. - */ - static createDataRepositoryButton(): SourceOperatorListButton { - return { - name: 'Data Repository', - description: 'Generic data repository', - iconSrc: RasterSourceType.ICON_URL, - sidenavConfig: {component: DataRepositoryComponent, keepParent: true}, - }; - } - - /** - * Default for a draw features entry. - */ - static createDrawFeaturesButton(): SourceOperatorListButton { - return { - name: 'Draw Features', - description: 'Draw features on the map', - icon: 'create', - sidenavConfig: {component: OlDrawFeaturesComponent, keepParent: true}, - }; - } - - /** - * Default for a custom features entry. - */ - static createCustomFeaturesButtons(): [SourceOperatorListButton, SourceOperatorListButton] { - return [ - { - name: 'Custom Features', - description: 'Add and use custom vector features like CSV', - iconSrc: CsvSourceType.ICON_URL, - sidenavConfig: {component: FeaturedbSourceListComponent, keepParent: true}, - onlyIfLoggedIn: true, - }, - { - name: 'Custom Features', - description: 'Log in to use custom vector data from, e.g., CSV files', - iconSrc: CsvSourceType.ICON_URL, - sidenavConfig: undefined, - onlyIfLoggedOut: true, - }, - ]; - } - - /** - * Default for a country polygon selection entry. - */ - static createCountryPolygonsButton(): SourceOperatorListButton { - return { - name: 'Country Selection', - description: 'Select country borders', - icon: 'location_on', - sidenavConfig: {component: CountryPolygonSelectionComponent, keepParent: true}, - }; - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/statistics-plot/statistics-plot.component.html b/projects/wave-core/src/lib/operators/dialogs/statistics-plot/statistics-plot.component.html deleted file mode 100644 index 78275673..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/statistics-plot/statistics-plot.component.html +++ /dev/null @@ -1,22 +0,0 @@ -Layer statistics plot -
    -
    - - - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/statistics-plot/statistics-plot.component.scss b/projects/wave-core/src/lib/operators/dialogs/statistics-plot/statistics-plot.component.scss deleted file mode 100644 index d6da83a8..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/statistics-plot/statistics-plot.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -:host { - display: block; - padding: 1rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/statistics-plot/statistics-plot.component.ts b/projects/wave-core/src/lib/operators/dialogs/statistics-plot/statistics-plot.component.ts deleted file mode 100644 index 5ec6932e..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/statistics-plot/statistics-plot.component.ts +++ /dev/null @@ -1,64 +0,0 @@ -import {Component, ChangeDetectionStrategy, AfterViewInit, OnDestroy, OnInit} from '@angular/core'; -import {FormGroup, FormBuilder, Validators} from '@angular/forms'; -import {ResultTypes} from '../../result-type.model'; -import {Operator} from '../../operator.model'; -import {Plot} from '../../../plots/plot.model'; -import {ProjectService} from '../../../project/project.service'; -import {WaveValidators} from '../../../util/form.validators'; -import {StatisticsType} from '../../types/statistics-type.model'; - -@Component({ - selector: 'wave-statistics-plot', - templateUrl: './statistics-plot.component.html', - styleUrls: ['./statistics-plot.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class StatisticsPlotComponent implements OnInit, AfterViewInit, OnDestroy { - form: FormGroup; - - ResultTypes = ResultTypes; - - constructor(private formBuilder: FormBuilder, private projectService: ProjectService) {} - - ngOnInit() { - this.form = this.formBuilder.group({ - layer: [undefined, Validators.required], - name: ['', [Validators.required, WaveValidators.notOnlyWhitespace]], - }); - } - - add() { - const sourceOperator: Operator = this.form.controls['layer'].value.operator; - const operator: Operator = new Operator({ - operatorType: new StatisticsType({ - raster_height: 256, - raster_width: 256, - }), - resultType: ResultTypes.PLOT, - projection: sourceOperator.projection, - pointSources: sourceOperator.resultType === ResultTypes.POINTS ? [sourceOperator] : undefined, - lineSources: sourceOperator.resultType === ResultTypes.LINES ? [sourceOperator] : undefined, - polygonSources: sourceOperator.resultType === ResultTypes.POLYGONS ? [sourceOperator] : undefined, - rasterSources: sourceOperator.resultType === ResultTypes.RASTER ? [sourceOperator] : undefined, - }); - - const plot = new Plot({ - name: this.form.controls['name'].value.toString(), - operator, - }); - - this.projectService.addPlot(plot); - } - - ngOnDestroy() {} - - ngAfterViewInit() { - setTimeout(() => { - this.form.updateValueAndValidity({ - onlySelf: false, - emitEvent: true, - }); - this.form.controls['layer'].updateValueAndValidity(); - }); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/textual-attribute-filter/textual-attribute-filter.component.html b/projects/wave-core/src/lib/operators/dialogs/textual-attribute-filter/textual-attribute-filter.component.html deleted file mode 100644 index 269062f4..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/textual-attribute-filter/textual-attribute-filter.component.html +++ /dev/null @@ -1,40 +0,0 @@ -Textual Attribute Filter -
    -
    - - - - - {{ attribute }} - - - - - is exactly - contains - starts with - - - - - - The search string must be non-empty. - - - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/textual-attribute-filter/textual-attribute-filter.component.scss b/projects/wave-core/src/lib/operators/dialogs/textual-attribute-filter/textual-attribute-filter.component.scss deleted file mode 100644 index f907881f..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/textual-attribute-filter/textual-attribute-filter.component.scss +++ /dev/null @@ -1,24 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -.actions { - text-align: right; - padding: 1rem; -} - -mat-form-field { - width: 100% !important; - margin: 0 0 1rem 0; -} - -.error { - color: var(--wave-warn-color, red); -} diff --git a/projects/wave-core/src/lib/operators/dialogs/textual-attribute-filter/textual-attribute-filter.component.ts b/projects/wave-core/src/lib/operators/dialogs/textual-attribute-filter/textual-attribute-filter.component.ts deleted file mode 100644 index 2a9719a8..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/textual-attribute-filter/textual-attribute-filter.component.ts +++ /dev/null @@ -1,125 +0,0 @@ -import {Observable} from 'rxjs'; -import {map, tap} from 'rxjs/operators'; -import {AfterViewInit, ChangeDetectionStrategy, Component} from '@angular/core'; - -import {VectorLayer} from '../../../layers/layer.model'; -import {ResultTypes} from '../../result-type.model'; -import {DataTypes} from '../../datatype.model'; -import {AbstractVectorSymbology} from '../../../layers/symbology/symbology.model'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {Operator} from '../../operator.model'; -import {ProjectService} from '../../../project/project.service'; -import {WaveValidators} from '../../../util/form.validators'; -import {TextualAttributeFilterEngineType, TextualAttributeFilterType} from '../../types/textual-attribute-filter-type.model'; -import {RandomColorService} from '../../../util/services/random-color.service'; - -/** - * This component allows creating the textual attribute filter operator. - */ -@Component({ - selector: 'wave-textual-attribute-filter', - templateUrl: './textual-attribute-filter.component.html', - styleUrls: ['./textual-attribute-filter.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class TextualAttributeFilterOperatorComponent implements AfterViewInit { - // for the template - ResultTypes = ResultTypes; - TextualAttributeFilterEngineType = TextualAttributeFilterEngineType; - - form: FormGroup; - attributes$: Observable>; - - constructor(private projectService: ProjectService, private formBuilder: FormBuilder, private randomColorService: RandomColorService) { - this.form = formBuilder.group({ - name: ['Filtered Values', [Validators.required, WaveValidators.notOnlyWhitespace]], - vectorLayer: [undefined, Validators.required], - attribute: [undefined, Validators.required], - engine: [TextualAttributeFilterEngineType.EXACT, Validators.required], - searchString: ['', [Validators.required, WaveValidators.notOnlyWhitespace]], - }); - - this.attributes$ = this.form.controls['vectorLayer'].valueChanges.pipe( - tap((layer) => { - // side effects!!! - this.form.controls['attribute'].setValue(undefined); - if (layer) { - this.form.controls['attribute'].enable({onlySelf: true}); - } else { - this.form.controls['attribute'].disable({onlySelf: true}); - } - }), - map((layer) => { - if (layer) { - return layer.operator.attributes - .filter((attribute: string) => { - return DataTypes.Alphanumeric === layer.operator.dataTypes.get(attribute); - }) - .toArray() - .sort(); - } else { - return []; - } - }), - ); - } - - ngAfterViewInit() { - // initially get attributes - setTimeout(() => this.form.controls['vectorLayer'].enable({emitEvent: true})); - } - - add(event: any) { - const vectorLayer: VectorLayer = this.form.controls['vectorLayer'].value; - const sourceOperator: Operator = vectorLayer.operator; - - const attributeName: string = this.form.controls['attribute'].value; - const engine: TextualAttributeFilterEngineType = this.form.controls['engine'].value; - const searchString: string = this.form.controls['searchString'].value; - - const name: string = this.form.controls['name'].value; - - const dict = { - operatorType: new TextualAttributeFilterType({ - attributeName: attributeName, - engine: engine, - searchString: searchString, - }), - resultType: sourceOperator.resultType, - projection: sourceOperator.projection, - attributes: sourceOperator.attributes, - dataTypes: sourceOperator.dataTypes, - units: sourceOperator.units, - pointSources: [], - lineSources: [], - polygonSources: [], - }; - - switch (sourceOperator.resultType) { - case ResultTypes.POINTS: - dict.pointSources.push(sourceOperator); - break; - case ResultTypes.LINES: - dict.lineSources.push(sourceOperator); - break; - case ResultTypes.POLYGONS: - dict.polygonSources.push(sourceOperator); - break; - default: - throw Error('Incompatible Input Type'); - } - - const operator = new Operator(dict); - - const symbology = (vectorLayer.symbology.clone() as any) as AbstractVectorSymbology; - symbology.fillRGBA = this.randomColorService.getRandomColorRgba(); - const layer = new VectorLayer({ - name: name, - operator: operator, - symbology: symbology, - clustered: vectorLayer.clustered, - }); - - this.projectService.addLayer(layer); - } -} diff --git a/projects/wave-core/src/lib/operators/dialogs/time-plot-operator/time-plot-operator.component.html b/projects/wave-core/src/lib/operators/dialogs/time-plot-operator/time-plot-operator.component.html deleted file mode 100644 index 0750c435..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/time-plot-operator/time-plot-operator.component.html +++ /dev/null @@ -1,44 +0,0 @@ -Time plot -
    -
    - -
    - - - - - {{ attribute }} - - - - - - - - - - {{ attribute }} - - - -
    - - - - The name must be non-empty. - - -
    -
    - -
    -
    diff --git a/projects/wave-core/src/lib/operators/dialogs/time-plot-operator/time-plot-operator.component.scss b/projects/wave-core/src/lib/operators/dialogs/time-plot-operator/time-plot-operator.component.scss deleted file mode 100644 index 07e352ee..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/time-plot-operator/time-plot-operator.component.scss +++ /dev/null @@ -1,20 +0,0 @@ -form { - height: 100%; - width: 100%; - box-sizing: border-box; -} - -.container { - overflow-y: auto; - padding: 0 1rem 1rem 1rem; -} - -mat-form-field { - width: 100%; - margin: 1rem 0; -} - -.actions { - text-align: right; - padding: 1rem; -} diff --git a/projects/wave-core/src/lib/operators/dialogs/time-plot-operator/time-plot-operator.component.ts b/projects/wave-core/src/lib/operators/dialogs/time-plot-operator/time-plot-operator.component.ts deleted file mode 100644 index 45675227..00000000 --- a/projects/wave-core/src/lib/operators/dialogs/time-plot-operator/time-plot-operator.component.ts +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Created by Julian on 23/06/2017. - */ -import {AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy, OnInit} from '@angular/core'; -import {AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators} from '@angular/forms'; -import {ResultTypes} from '../../result-type.model'; -import {Operator} from '../../operator.model'; -import {Plot} from '../../../plots/plot.model'; -import {ProjectService} from '../../../project/project.service'; -import {WaveValidators} from '../../../util/form.validators'; -import {TimePlotType} from '../../types/timeplot-type.model'; - -@Component({ - selector: 'wave-time-plot-operator', - templateUrl: './time-plot-operator.component.html', - styleUrls: ['./time-plot-operator.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class TimePlotComponent implements OnInit, AfterViewInit, OnDestroy { - form: FormGroup; - - ResultTypes = ResultTypes; - - constructor(private formBuilder: FormBuilder, private projectService: ProjectService) {} - - ngOnInit() { - this.form = this.formBuilder.group({ - layer: [undefined, Validators.required], - attribute: [undefined, Validators.required], - name: ['', [Validators.required, WaveValidators.notOnlyWhitespace]], - isGrouping: [false, [Validators.required]], - grouping: [undefined, this.ifEnabled], - }); - } - - add() { - const sourceOperator: Operator = this.form.controls['layer'].value.operator; - - const operator: Operator = new Operator({ - operatorType: new TimePlotType({ - attribute: this.form.controls['attribute'].value.toString(), - isGrouping: this.form.controls['isGrouping'].value, - grouping: this.form.controls['isGrouping'].value ? this.form.controls['grouping'].value.toString() : null, - time: 'DateLastEdited', - inputType: sourceOperator.resultType, - }), - resultType: ResultTypes.PLOT, - projection: sourceOperator.projection, - pointSources: sourceOperator.resultType === ResultTypes.POINTS ? [sourceOperator] : undefined, - lineSources: sourceOperator.resultType === ResultTypes.LINES ? [sourceOperator] : undefined, - polygonSources: sourceOperator.resultType === ResultTypes.POLYGONS ? [sourceOperator] : undefined, - }); - - const plot = new Plot({ - name: this.form.controls['name'].value.toString(), - operator: operator, - }); - - this.projectService.addPlot(plot); - } - - ngOnDestroy() {} - - ngAfterViewInit() { - setTimeout(() => { - this.form.updateValueAndValidity({ - onlySelf: false, - emitEvent: true, - }); - this.form.controls['layer'].updateValueAndValidity(); - }); - } - - ifEnabled(): ValidatorFn { - return (control: AbstractControl): {[key: string]: any} => { - return !control.value && !this.form.controls['isGrouping'] ? {valueRequired: {value: control.value}} : null; - }; - } -} diff --git a/projects/wave-core/src/lib/operators/operator-type-parameter-options.model.ts b/projects/wave-core/src/lib/operators/operator-type-parameter-options.model.ts deleted file mode 100644 index b2ed996e..00000000 --- a/projects/wave-core/src/lib/operators/operator-type-parameter-options.model.ts +++ /dev/null @@ -1,475 +0,0 @@ -import {OptionsDict} from './operator-type.model'; - -export type ParameterName = string; - -export const enum ParameterOptionType { - NUMBER_ARRAY, - STRING_ARRAY, - NUMBER_RANGE, - DICT_ARRAY, - EMPTY, -} - -export interface NumberParameterArrayConfig { - kind: ParameterOptionType.NUMBER_ARRAY; - options: Array; -} - -export interface EmptyContainerConfig { - kind: ParameterOptionType.EMPTY; -} - -export interface StringParameterArrayConfig { - kind: ParameterOptionType.STRING_ARRAY; - options: Array; -} - -export interface NumberParameterRangeConfig { - kind: ParameterOptionType.NUMBER_RANGE; - start: number; - stop: number; - step?: number; -} - -export interface DictParameterArrayConfig { - kind: ParameterOptionType.DICT_ARRAY; - options: Array; -} - -export type ParameterContainerType = - | EmptyParameterContainer - | NumberParameterArray - | NumberParameterRange - | StringParameterArray - | DictParameterArray; - -export enum TickType { - DISCRETE, - CONTINUOUS, -} - -/** - * Parameter option container provide the valid inputs for operator parematers. - * This is abstracted by ticks which are either in a numberic space or an enumeration of predefined values. - */ -export abstract class AbstractParameterContainer { - /** - * Get the parameter type. - */ - abstract get parameterType(): ParameterOptionType; - - /** - * Get the tick type, which indicates how to step through options. - */ - abstract get tickType(): TickType; - - /** - * Get a display value for a tick. - */ - abstract getDisplayValueForTick(tick: number): string | undefined; - - /** - * Check if a value is in this option container. - */ - containsValue(value: T): boolean { - return !!this.getTickForValue(value); - } - - /** - * Get the value for a tick. - */ - abstract getValueForTick(tick: number): T | undefined; - - /** - * Get the tick for a value. - */ - abstract getTickForValue(value: T): number | undefined; - - /** - * Check if a tick is valid. - */ - isValidTick(tick: number): boolean { - if (tick < this.firstTick || tick > this.lastTick) { - return false; - } - if (this.tickType === TickType.DISCRETE) { - return Number.isInteger(tick); - } - return true; - } - - /** - * Get the first possible tick. - */ - abstract get firstTick(): number; - - /** - * Get the last possible tick. - */ - abstract get lastTick(): number; - - /** - * Get the tick step size. Default = 1. - */ - get tickStepSize(): number { - return 1; - } - - /** - * Check if the container has ticks. - */ - hasTicks() { - return this.firstTick < this.lastTick; - } - - /** - * Generate an empty parameter option container. - */ - static getEmptyOption(): EmptyParameterContainer { - return EMPTY_OPTION; - } -} - -/** - * An empty parameter option container. - */ -export class EmptyParameterContainer extends AbstractParameterContainer { - constructor() { - super(); - } - - get parameterType(): ParameterOptionType { - return ParameterOptionType.EMPTY; - } - - get firstTick(): number { - return 0; - } - - getDisplayValueForTick(tick: number): string | undefined { - return undefined; - } - - getTickForValue(value: number): number | undefined { - return undefined; - } - - getValueForTick(tick: number): number | string | undefined { - return undefined; - } - - get lastTick(): number { - return 0; - } - - get tickType(): TickType { - return TickType.DISCRETE; - } -} - -/** - * Singleton empty option container. - */ -const EMPTY_OPTION = new EmptyParameterContainer(); - -/** - * A parameter option container for numerical parameters. - */ -export class NumberParameterArray extends AbstractParameterContainer { - /** - * The list of all valid options. - */ - options: Array; - - constructor(config: NumberParameterArrayConfig) { - super(); - this.options = config.options; - } - - get parameterType(): ParameterOptionType { - return ParameterOptionType.NUMBER_ARRAY; - } - - static fromDict(dict: NumberParameterArrayConfig) { - return new NumberParameterArray(dict); - } - - toDict(): NumberParameterArrayConfig { - return { - options: this.options, - kind: ParameterOptionType.NUMBER_ARRAY, - }; - } - - get firstTick(): number { - return 0; - } - - getDisplayValueForTick(tick: number): string | undefined { - return this.getValueForTick(tick).toString(); - } - - getTickForValue(value: number): number | undefined { - const findIndex = this.options.findIndex((x) => x === value); - if (findIndex < 0) { - return undefined; - } - return findIndex; - } - - getValueForTick(tick: number): number | undefined { - if (!this.isValidTick(tick)) { - return undefined; - } - return this.options[tick]; - } - - get lastTick(): number { - return this.options.length - 1; - } - - get tickType(): TickType { - return TickType.DISCRETE; - } -} - -/** - * A parameter option container for string parameters. - */ -export class StringParameterArray extends AbstractParameterContainer { - /** - * The list of all valid options. - */ - options: Array; - - constructor(config: StringParameterArrayConfig) { - super(); - this.options = config.options; - } - - get parameterType(): ParameterOptionType { - return ParameterOptionType.STRING_ARRAY; - } - - static fromDict(dict: StringParameterArrayConfig) { - return new StringParameterArray(dict); - } - - get firstTick(): number { - return 0; - } - - getDisplayValueForTick(tick: number): string | undefined { - return this.getValueForTick(tick).toString(); - } - - getTickForValue(value: string): number | undefined { - const findIndex = this.options.findIndex((x) => x === value); - if (findIndex < 0) { - return undefined; - } - return findIndex; - } - - getValueForTick(tick: number): string | undefined { - if (!this.isValidTick(tick)) { - return undefined; - } - return this.options[tick]; - } - - get lastTick(): number { - return this.options.length - 1; - } - - get tickType(): TickType { - return TickType.DISCRETE; - } -} - -/** - * An interface for numeric range parameters. - */ -export class NumberParameterRange extends AbstractParameterContainer { - /** - * Range start. - */ - start: number; - /** - * Range end. - */ - stop: number; - /** - * Range step size. - */ - step = 1; - - constructor(config: NumberParameterRangeConfig) { - super(); - this.start = config.start; - this.stop = config.stop; - this.step = config.step ? config.step : 1; - } - - get parameterType(): ParameterOptionType { - return ParameterOptionType.NUMBER_RANGE; - } - - static fromDict(dict: NumberParameterRangeConfig) { - return new NumberParameterRange(dict); - } - - toDict(): NumberParameterRangeConfig { - return { - start: this.start, - stop: this.stop, - step: this.step, - kind: ParameterOptionType.NUMBER_RANGE, - }; - } - - get firstTick(): number { - return this.start; - } - - getDisplayValueForTick(tick: number): string | undefined { - return this.getValueForTick(tick).toString(); - } - - getTickForValue(value: number): number | undefined { - return this.getValueForTick(value); - } - - getValueForTick(tick: number): number | undefined { - if (!this.isValidTick(tick)) { - return undefined; - } - return tick; - } - - get lastTick(): number { - return this.stop; - } - - get tickStepSize(): number { - return this.step; - } - - get tickType(): TickType { - return TickType.CONTINUOUS; - } -} - -/** - * An interface for complex parameter options. - * The type of the option type is generic but has to implement OptionsDict. - */ -export class DictParameterArray extends AbstractParameterContainer { - /** - * List of all valid options. - */ - options: Array; - - constructor(config: DictParameterArrayConfig) { - super(); - this.options = config.options; - } - - get parameterType(): ParameterOptionType { - return ParameterOptionType.DICT_ARRAY; - } - - static fromDict(dict: DictParameterArrayConfig): DictParameterArray { - return new DictParameterArray(dict); - } - - toDict(): DictParameterArrayConfig { - return { - options: this.options, - kind: ParameterOptionType.DICT_ARRAY, - }; - } - - get firstTick(): number { - return 0; - } - - getDisplayValueForTick(tick: number): string | undefined { - return this.getValueForTick(tick).displayValue.toString(); - } - - getTickForValue(value: T): number | undefined { - const findIndex = this.options.findIndex((x) => x.displayValue === value.displayValue); // TODO: review if displayValue is distinct - if (findIndex < 0) { - return undefined; - } - return findIndex; - } - - getValueForTick(tick: number): T | undefined { - if (!this.isValidTick(tick)) { - return undefined; - } - return this.options[tick]; - } - - get lastTick(): number { - return this.options.length - 1; - } - - get tickType(): TickType { - return TickType.DISCRETE; - } -} - -/** - * Dictionary for serializing the operator type. - */ -export interface OperatorTypeParameterOptionsConfig { - operatorType: string; -} - -/** - * The operator basic type. - */ -export abstract class OperatorTypeParameterOptions { - operatorType: string; - - constructor(config: OperatorTypeParameterOptionsConfig) { - this.operatorType = config.operatorType; - } - - /** - * Serialize the operator type. - */ - abstract toDict(): OperatorTypeParameterOptionsConfig; - - /** - * Get the parameter option type for a parameter name. - */ - public getParameterOption(parameterName: ParameterName): ParameterContainerType { - const res: [ParameterName, ParameterContainerType] = this.getParameterOptions().find(([pN, _]) => pN === parameterName); - if (!res) { - return AbstractParameterContainer.getEmptyOption(); - } - const [_, pOption] = res; - return pOption; - } - - /** - * Get the parameter options as array of tuples [ParameterName, ParameterContainerType]. - */ - public abstract getParameterOptions(): Array<[ParameterName, ParameterContainerType]>; - - /** - * Get the parameter options as array of tuples [ParameterName, ParameterOptionType]. - */ - public abstract getParametersTypes(): Array<[ParameterName, ParameterOptionType]>; - - /** - * Get a list of all parameter names. - */ - public getParameterNames(): Array { - return this.getParametersTypes().map(([n, _]) => n); - } -} diff --git a/projects/wave-core/src/lib/operators/operator-type.model.ts b/projects/wave-core/src/lib/operators/operator-type.model.ts deleted file mode 100644 index 3585e4a8..00000000 --- a/projects/wave-core/src/lib/operators/operator-type.model.ts +++ /dev/null @@ -1,129 +0,0 @@ -// eslint-disable-line - -/** - * Options allowed when cloning the operator - */ -export interface OperatorTypeCloneOptions {} // eslint-disable-line @typescript-eslint/no-empty-interface - -/** - * Dictionary for querying the server. - */ -export interface OperatorTypeMappingDict {} // eslint-disable-line @typescript-eslint/no-empty-interface - -/** - * Dictionary for serializing the operator type. - */ -export interface OperatorTypeDict { - operatorType: string; -} - -/** - * Interface required for complex operator parameter options. - * It represents display values of type options. - */ -export interface OptionsDict { - displayValue: string; -} - -/** - * The possible types of parameter values - */ -export type ParameterValue = number | string | OptionsDict; - -/** - * The operator basic type. - */ -export abstract class OperatorType { - /** - * Each operator type must have a method that returns - * an icon as a data uri image. This provides a default - * out of the operator name. - */ - public static createIconDataUrl(iconName: string) { - // TODO: replace with proper icons - // from `http://stackoverflow.com/questions/3426404/ - // create-a-hexadecimal-colour-based-on-a-string-with-javascript` - const hashCode = (str: string) => { - // java String#hashCode - let hash = 0; - for (let i = 0; i < str.length; i++) { - hash = str.charCodeAt(i) + ((hash << 5) - hash); // eslint-disable-line no-bitwise - } - return hash; - }; - const intToRGB = (i: number) => { - const c = (i & 0x00ffffff).toString(16).toUpperCase(); // eslint-disable-line no-bitwise - - return '00000'.substring(0, 6 - c.length) + c; - }; - - const color = '#' + intToRGB(hashCode(iconName)); - const size = 64; - - const canvas = document.createElement('canvas'); - canvas.width = size; - canvas.height = size; - const context = canvas.getContext('2d'); - context.fillStyle = color; - context.fillRect(0, 0, 64, 64); - return canvas.toDataURL('image/png'); - } - - /** - * Get the server-side name of the type. - */ - abstract getMappingName(): string; - - /** - * Human-readable type name. - */ - abstract toString(): string; - - /** - * Serialize the operator type. - */ - abstract toDict(): OperatorTypeDict; - - /** - * Create query parameter. - */ - abstract toMappingDict(): OperatorTypeMappingDict; - - /** - * Icon respresentation of the operator. - */ - abstract getIconUrl(): string; - - /** - * Get the value of a parameter - */ - public getParameterValue(parameterName: string): ParameterValue | undefined { - return undefined; - } - - /** - * Get the DisplayValue of a parameter - */ - public getParameterDisplayValue(parameterName: string): string | undefined { - const parameterValue = this.getParameterValue(parameterName); - if (!parameterValue) { - return undefined; - } - // parameters are either objects of 'OptionDict' i.e. they have a 'displayValue' or 'number | string' - if (typeof parameterValue === 'object') { - return parameterValue.displayValue; - } - return parameterValue.toString(); - } - - /** - * Get a human readable parameter list. - */ - abstract getParametersAsStrings(): Array<[string, string]>; - - /** - * clone an operator type with modified parameters - * @param options a dictionary with modifications - */ - abstract cloneWithModifications(options?: OperatorTypeCloneOptions): OperatorType; -} diff --git a/projects/wave-core/src/lib/operators/operator.model.ts b/projects/wave-core/src/lib/operators/operator.model.ts deleted file mode 100644 index 24fb0f26..00000000 --- a/projects/wave-core/src/lib/operators/operator.model.ts +++ /dev/null @@ -1,455 +0,0 @@ -import {List as ImmutableList, Map as ImmutableMap} from 'immutable'; - -import {ResultType, ResultTypes} from './result-type.model'; -import {Projection, Projections} from './projection.model'; -import {Unit, UnitDict} from './unit.model'; -import {DataType, DataTypes} from './datatype.model'; - -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from './operator-type.model'; -import {OperatorTypeFactory} from './types/type-factory.service'; -import {ProjectionType} from './types/projection-type.model'; -import {OperatorTypeParameterOptions, OperatorTypeParameterOptionsConfig} from './operator-type-parameter-options.model'; -import {OperatorTypeParameterOptionsFactory} from './parameter-options/type-parameter-options-factory.service'; - -type OperatorId = number; -type AttributeName = string; - -/** - * Interface for Operator constructor. - */ -interface OperatorConfig { - operatorType: OperatorType; - operatorTypeParameterOptions?: OperatorTypeParameterOptions; - resultType: ResultType; - projection: Projection; - attributes?: ImmutableList | Array; - dataTypes?: ImmutableMap | Map; - units?: ImmutableMap | Map; - rasterSources?: ImmutableList | Array; - pointSources?: ImmutableList | Array; - lineSources?: ImmutableList | Array; - polygonSources?: ImmutableList | Array; -} - -interface OperatorCloneOptions { - operatorType?: OperatorType; - operatorTypeParameterOptions?: OperatorTypeParameterOptions; -} - -/** - * Serialization interface - */ -export interface OperatorDict { - id: number; - operatorType: OperatorTypeDict; - operatorTypeParameterOptions: OperatorTypeParameterOptionsConfig; - resultType: string; - projection: string; - attributes: Array; - dataTypes: Array<[string, string]>; - units: Array<[string, UnitDict]>; - rasterSources: Array; - pointSources: Array; - lineSources: Array; - polygonSources: Array; -} - -/** - * Serialization for mapping query. - */ -interface QueryDict { - type: string; - params: OperatorTypeMappingDict; - sources?: { - raster?: Array; - points?: Array; - lines?: Array; - polygons?: Array; - }; -} - -/** - * An operator represents a query graph consisting of source operators. - * It has several metadata fields for e.g. parameters and projection. - */ -export class Operator { - static readonly RASTER_ATTRIBTE_NAME: AttributeName = 'value'; - - private static _nextOperatorId = 1; // used for operator id generation - - private _id: OperatorId; - - private _resultType: ResultType; - private _operatorType: OperatorType; - private _operatorTypeParameterOptions: OperatorTypeParameterOptions; - - private _attributes: ImmutableList; - private _dataTypes: ImmutableMap; - private _units: ImmutableMap; - - private _projection: Projection; - - private rasterSources: ImmutableList; - private pointSources: ImmutableList; - private lineSources: ImmutableList; - private polygonSources: ImmutableList; - - /** - * Deserialize an operator from a json string. - */ - static fromJSON(json: string): Operator { - return this.fromDict(JSON.parse(json)); - } - - /** - * Deserialize an operator from a dictionary. - * @param operatorDict the Dictionary - * @param operators a map from serialized ids to already deserialized operators - * @returns an operator - */ - static fromDict(operatorDict: OperatorDict, operators = new Map()): Operator { - // the operator was deserialized before, so just return it - if (operators.has(operatorDict.id)) { - return operators.get(operatorDict.id); - } - - // create the operator from the dict (recursively) - const operator = new Operator({ - operatorType: OperatorTypeFactory.fromDict(operatorDict.operatorType), - operatorTypeParameterOptions: operatorDict.operatorTypeParameterOptions - ? OperatorTypeParameterOptionsFactory.fromDict(operatorDict.operatorTypeParameterOptions) - : undefined, - resultType: ResultTypes.fromCode(operatorDict.resultType), - projection: Projections.fromCode(operatorDict.projection), - attributes: ImmutableList(operatorDict.attributes), - dataTypes: ImmutableMap( - (operatorDict.dataTypes as Array<[string, string]>).map(([name, dataTypeCode]) => [name, DataTypes.fromCode(dataTypeCode)]), - ), - units: ImmutableMap( - (operatorDict.units as Array<[string, UnitDict]>).map(([name, unitDict]) => [name, Unit.fromDict(unitDict)]), - ), - rasterSources: ImmutableList(operatorDict.rasterSources.map((dict) => Operator.fromDict(dict, operators))), - pointSources: ImmutableList(operatorDict.pointSources.map((dict) => Operator.fromDict(dict, operators))), - lineSources: ImmutableList(operatorDict.lineSources.map((dict) => Operator.fromDict(dict, operators))), - polygonSources: ImmutableList(operatorDict.polygonSources.map((dict) => Operator.fromDict(dict, operators))), - }); - - // store the operator s.th. the same operator is not deserialized into two instances - operators.set(operatorDict.id, operator); - - return operator; - } - - /** - * Instantiate an operator. - * - * @param config.operatorType The mapping type name of the operator. - * @param config.resultType A {@link resultType}. - * @param config.projection A {@link Projection}. - * @param config.displayName The user-given name of this operator instance. - * @param config.rasterSources A list of operators with {@link ResultType} `RASTER`. - * @param config.pointSources A list of operators with {@link ResultType} `POINTS`. - * @param config.lineSources A list of operators with {@link ResultType} `LINES`. - * @param config.polygonSources A list of operators with {@link ResultType} `POLYGONS`. - * - */ - constructor(config: OperatorConfig) { - this._id = Operator.nextOperatorId; - - this._operatorType = config.operatorType; - this._resultType = config.resultType; - - this._projection = config.projection; - - if (config.attributes) { - this._attributes = - config.attributes instanceof ImmutableList - ? (config.attributes as ImmutableList) - : ImmutableList(config.attributes as Array); - } else { - this._attributes = ImmutableList(); - } - - if (config.dataTypes) { - this._dataTypes = - config.dataTypes instanceof ImmutableMap - ? (config.dataTypes as ImmutableMap) - : ImmutableMap((config.dataTypes as Map).entries()); - } else { - this._dataTypes = ImmutableMap(); - } - - if (config.units) { - this._units = - config.units instanceof ImmutableMap - ? (config.units as ImmutableMap) - : ImmutableMap((config.units as Map).entries()); - } else { - this._units = ImmutableMap(); - } - - if (config.operatorTypeParameterOptions) { - this._operatorTypeParameterOptions = config.operatorTypeParameterOptions; - } else { - this._operatorTypeParameterOptions = undefined; // TODO: handle operators without parameters? - } - - const returnChecked = (source: ImmutableList | Array, type: ResultType): ImmutableList => { - if (source) { - const list = - source instanceof ImmutableList ? (source as ImmutableList) : ImmutableList(source as Array); - - if (list.filter((op) => op.resultType !== type).size > 0) { - throw Error(`The Input Operator is not of type ${type.toString()}.`); - } else { - return list; - } - } else { - return ImmutableList(); - } - }; - - this.rasterSources = returnChecked(config.rasterSources, ResultTypes.RASTER); - this.pointSources = returnChecked(config.pointSources, ResultTypes.POINTS); - this.lineSources = returnChecked(config.lineSources, ResultTypes.LINES); - this.polygonSources = returnChecked(config.polygonSources, ResultTypes.POLYGONS); - } - - /** - * Retrieve a new unique id. - * @return operator id - */ - private static get nextOperatorId(): OperatorId { - return this._nextOperatorId++; - } - - /** - * Unique id of this operator instance. - */ - get id(): OperatorId { - return this._id; - } - - /** - * The type of the operator. - */ - get operatorType(): OperatorType { - return this._operatorType; - } - - get operatorTypeParameterOptions(): OperatorTypeParameterOptions | undefined { - return this._operatorTypeParameterOptions; - } - - /** - * Retrieve the output result type. - */ - get resultType(): ResultType { - return this._resultType; - } - - /** - * Retrieve the output projection. - */ - get projection(): Projection { - return this._projection; - } - - /** - * Retrieve the output attributes. - */ - get attributes(): ImmutableList { - return this._attributes; - } - - /** - * Retrieve the attribute data type. - */ - getDataType(attribute: AttributeName): DataType { - return this._dataTypes.get(attribute); - } - - /** - * Retrieve all data types. - */ - get dataTypes(): ImmutableMap { - return this._dataTypes; - } - - /** - * Retrieve the attribute unit. - */ - getUnit(attribute: AttributeName): Unit { - return this._units.get(attribute); - } - - /** - * Retrieve all units. - */ - get units(): ImmutableMap { - return this._units; - } - - /** - * The total amount of sources. - */ - get sourceCount(): number { - return this.rasterSources.size + this.pointSources.size + this.lineSources.size + this.polygonSources.size; - } - - /** - * Retrieve a source by id. - * - * @param id The id of the source operator. - */ - getAnySource(id: number) { - const predicate = (operator: Operator) => operator._id === id; - - for (const source of [this.rasterSources, this.pointSources, this.lineSources, this.polygonSources]) { - const result = source.find(predicate); - - if (result) { - return result; - } - } - - throw Error(`getAnySource: no source found with id ${id} in ${JSON.stringify(this)}`); - } - - /** - * Does the operator has sources or it it a **source operator**? - */ - hasSources(): boolean { - return this.rasterSources.size > 0 || this.pointSources.size > 0 || this.lineSources.size > 0 || this.polygonSources.size > 0; - } - - /** - * Retrieve the sources by type. - * - * @param sourceType The {@link resultType} of the source. - */ - getSources(sourceType: ResultType): ImmutableList { - switch (sourceType) { - case ResultTypes.RASTER: - return this.rasterSources; - case ResultTypes.POINTS: - return this.pointSources; - case ResultTypes.LINES: - return this.lineSources; - case ResultTypes.POLYGONS: - return this.polygonSources; - default: - throw Error('Invalid Source Type'); - } - } - - /** - * Return the operator with an optional projection operator to - * comply with the desired {@link Projection}. - * - * @param projection The desired output projection. - */ - getProjectedOperator(projection: Projection): Operator { - if (projection === this.projection) { - return this; - } else { - return new Operator({ - operatorType: new ProjectionType({ - srcProjection: this.projection, - destProjection: projection, - }), - operatorTypeParameterOptions: this._operatorTypeParameterOptions, - resultType: this.resultType, - projection, - attributes: this._attributes, - dataTypes: this._dataTypes, - units: this._units, - rasterSources: this.resultType === ResultTypes.RASTER ? ImmutableList.of(this) : ImmutableList(), - pointSources: this.resultType === ResultTypes.POINTS ? ImmutableList.of(this) : ImmutableList(), - lineSources: this.resultType === ResultTypes.LINES ? ImmutableList.of(this) : ImmutableList(), - polygonSources: this.resultType === ResultTypes.POLYGONS ? ImmutableList.of(this) : ImmutableList(), - }); - } - } - - /** - * String representation of the operator as query parameter in JSON format. - */ - toQueryJSON(): string { - return JSON.stringify(this.toQueryDict()); - } - - toDict(): OperatorDict { - return { - id: this._id, - resultType: this._resultType.getCode(), - operatorType: this._operatorType.toDict(), - operatorTypeParameterOptions: this._operatorTypeParameterOptions ? this._operatorTypeParameterOptions.toDict() : undefined, - projection: this._projection.getCode(), - attributes: this._attributes.toArray(), - dataTypes: this._dataTypes.map((datatype) => datatype.getCode()).toArray(), - units: this._units.map((unit) => unit.toDict()).toArray(), - rasterSources: this.rasterSources.map((operator) => operator.toDict()).toArray(), - pointSources: this.pointSources.map((operator) => operator.toDict()).toArray(), - lineSources: this.lineSources.map((operator) => operator.toDict()).toArray(), - polygonSources: this.polygonSources.map((operator) => operator.toDict()).toArray(), - }; - } - - toJSON(): string { - return JSON.stringify(this.toDict()); - } - - /** - * Dictionary reprensentation of the operator as query parameter. - */ - toQueryDict(): QueryDict { - const dict: QueryDict = { - type: this._operatorType.getMappingName(), - params: this._operatorType.toMappingDict(), - }; - - if (this.hasSources()) { - const sources: {[index: string]: Array} = {}; - - const sourcesList: Array<[string, ImmutableList]> = [ - [ResultTypes.RASTER.getCode(), this.rasterSources], - [ResultTypes.POINTS.getCode(), this.pointSources], - [ResultTypes.LINES.getCode(), this.lineSources], - [ResultTypes.POLYGONS.getCode(), this.polygonSources], - ]; - for (const [sourceString, source] of sourcesList) { - if (source.size > 0) { - sources[sourceString] = source.map((operator: Operator) => operator.toQueryDict()).toArray(); - } - } - - dict.sources = sources; - } - - return dict; - } - - /** - * clone an operator with modified parameters - * @param options a dictionary with modifications - */ - - public cloneWithModifications(options?: OperatorCloneOptions): Operator { - return new Operator({ - operatorType: options.operatorType ? options.operatorType : this._operatorType, - operatorTypeParameterOptions: options.operatorTypeParameterOptions - ? options.operatorTypeParameterOptions - : this._operatorTypeParameterOptions, - resultType: this._resultType, - projection: this._projection, - attributes: this._attributes, - dataTypes: this._dataTypes, - units: this._units, - rasterSources: this.rasterSources, - pointSources: this.pointSources, - lineSources: this.lineSources, - polygonSources: this.polygonSources, - }); - } -} diff --git a/projects/wave-core/src/lib/operators/parameter-options/gdal-source-parameter-options.model.ts b/projects/wave-core/src/lib/operators/parameter-options/gdal-source-parameter-options.model.ts deleted file mode 100644 index 82b52fed..00000000 --- a/projects/wave-core/src/lib/operators/parameter-options/gdal-source-parameter-options.model.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { - DictParameterArray, - DictParameterArrayConfig, - OperatorTypeParameterOptions, - OperatorTypeParameterOptionsConfig, - ParameterName, - ParameterOptionType, -} from '../operator-type-parameter-options.model'; - -import {GdalSourceType} from '../types/gdal-source-type.model'; -import {OptionsDict} from '../operator-type.model'; -import {MappingRasterMethodology} from '../dialogs/data-repository/mapping-source.model'; - -/** - * Dictionary for serializing the operator type. - */ -export interface GdalSourceParameterOptionsConfig extends OperatorTypeParameterOptionsConfig { - channelConfig: DictParameterArrayConfig; -} - -/** - * Interface required for complex operator parameter options. - * GdalSource requires an interface with channelNumber parameter. - */ -export interface GdalSourceChannelOptions extends OptionsDict { - channelNumber: number; - methodology?: MappingRasterMethodology; -} - -/** - * GDAL source operator parameter options. - */ -export class GdalSourceParameterOptions extends OperatorTypeParameterOptions { - private channelConfig: DictParameterArray; - - constructor(config: GdalSourceParameterOptionsConfig) { - super(config); - this.channelConfig = DictParameterArray.fromDict(config.channelConfig); - } - - static fromDict(dict: GdalSourceParameterOptionsConfig) { - return new GdalSourceParameterOptions(dict); - } - - getParameterOptions(): Array<[ParameterName, DictParameterArray]> { - return [['channelConfig', this.channelConfig]]; - } - - toDict(): GdalSourceParameterOptionsConfig { - return { - operatorType: GdalSourceType.TYPE, - channelConfig: this.channelConfig.toDict(), - }; - } - - getParametersTypes(): Array<[ParameterName, ParameterOptionType]> { - return [['channelConfig', this.channelConfig.parameterType]]; - } -} diff --git a/projects/wave-core/src/lib/operators/parameter-options/layer-list-workflow-parameter-slider/layer-list-workflow-parameter-slider.component.html b/projects/wave-core/src/lib/operators/parameter-options/layer-list-workflow-parameter-slider/layer-list-workflow-parameter-slider.component.html deleted file mode 100644 index 2adb17d7..00000000 --- a/projects/wave-core/src/lib/operators/parameter-options/layer-list-workflow-parameter-slider/layer-list-workflow-parameter-slider.component.html +++ /dev/null @@ -1,16 +0,0 @@ -
    - - - -
    {{ parameterDisplayString }}: {{ parameterDisplayValue }}
    - - -
    -
    diff --git a/projects/wave-core/src/lib/operators/parameter-options/layer-list-workflow-parameter-slider/layer-list-workflow-parameter-slider.component.scss b/projects/wave-core/src/lib/operators/parameter-options/layer-list-workflow-parameter-slider/layer-list-workflow-parameter-slider.component.scss deleted file mode 100644 index e39945bd..00000000 --- a/projects/wave-core/src/lib/operators/parameter-options/layer-list-workflow-parameter-slider/layer-list-workflow-parameter-slider.component.scss +++ /dev/null @@ -1,9 +0,0 @@ -:host { - padding-left: 8px; - padding-right: 8px; - font-size: 12px; -} - -.mat-slider { - width: 100%; -} diff --git a/projects/wave-core/src/lib/operators/parameter-options/layer-list-workflow-parameter-slider/layer-list-workflow-parameter-slider.component.ts b/projects/wave-core/src/lib/operators/parameter-options/layer-list-workflow-parameter-slider/layer-list-workflow-parameter-slider.component.ts deleted file mode 100644 index caceee12..00000000 --- a/projects/wave-core/src/lib/operators/parameter-options/layer-list-workflow-parameter-slider/layer-list-workflow-parameter-slider.component.ts +++ /dev/null @@ -1,128 +0,0 @@ -import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'; -import {AbstractSymbology} from '../../../layers/symbology/symbology.model'; -import {Layer} from '../../../layers/layer.model'; -import {AbstractParameterContainer, ParameterContainerType, ParameterName} from '../../operator-type-parameter-options.model'; -import {ProjectService} from '../../../project/project.service'; -import {ParameterValue} from '../../operator-type.model'; - -/** - * A component which allows to change operator parameters using a slider. - * Inputs are the layer, the parameter name and a display name for the parameter. - */ -@Component({ - selector: 'wave-layer-list-workflow-parameter-slider', - templateUrl: 'layer-list-workflow-parameter-slider.component.html', - styleUrls: ['layer-list-workflow-parameter-slider.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LayerListWorkflowParameterSliderComponent implements OnChanges, OnInit { - /** - * The layer which is updated - */ - @Input() layer: Layer; - /** - * The layer parameter to update - */ - @Input() parameterName: ParameterName; - /** - * The layer parameter display name - */ - @Input() parameterDisplayName = undefined; - - // The changes by slider concept requires a range (start, stop, step) of parameters. - sliderRangeStart = 0; - sliderRangeStop = 0; - sliderRangeStep = 1; - // The current slider value - sliderValue = 0; - - // the parameter option provider - parameterOptionContainer: ParameterContainerType; - // the selected parameter option value - parameterValue: ParameterValue; - - constructor(public changeDetectorRef: ChangeDetectorRef, public projectService: ProjectService) {} - - ngOnChanges(changes: SimpleChanges): void { - for (const propName in changes) { - // eslint-disable-line guard-for-in - switch (propName) { - case 'parameterDisplayName': - case 'parameterName': { - this.changeDetectorRef.markForCheck(); - break; - } - case 'layer': { - this.updateParameterOptions(); - this.changeDetectorRef.markForCheck(); - break; - } - default: { - // DO NOTHING - } - } - } - } - - get parameterDisplayString(): string { - return this.parameterDisplayName ? this.parameterDisplayName : this.parameterName; - } - - get parameterDisplayValue(): string { - return this.parameterOptionContainer.getDisplayValueForTick(this.sliderValue); - } - - get hasParameterOptions(): boolean { - return !!this.parameterOptionContainer && this.parameterOptionContainer.hasTicks(); - } - - private updateParameterOptions() { - if (this.layer && this.layer.operator && this.layer.operator.operatorType && this.layer.operator.operatorTypeParameterOptions) { - const currentParameterValue = this.layer.operator.operatorType.getParameterValue(this.parameterName); - const currentParameterOptionContainer = this.layer.operator.operatorTypeParameterOptions.getParameterOption(this.parameterName); - this.parameterValue = currentParameterValue; - this.parameterOptionContainer = currentParameterOptionContainer; - - this.sliderRangeStart = this.parameterOptionContainer.firstTick; - this.sliderRangeStop = this.parameterOptionContainer.lastTick; - this.sliderValue = (this.parameterOptionContainer as AbstractParameterContainer).getTickForValue( - this.parameterValue, - ); - } - } - - /** - * The main update method of the component is called from the template when the slider changes. - */ - update(event: any) { - // to update an operator, a dict with type options is generated. - const operatorTypeOptions = {}; - - // set the parameterName entry to the value of the current slider tick. - operatorTypeOptions[this.parameterName] = this.parameterOptionContainer.getValueForTick(this.sliderValue); - - // clone the operatorType (this is the mapping operator) and apply the modifications from the options dict. - const operatorTypeClone = this.layer.operator.operatorType.cloneWithModifications(operatorTypeOptions); - - // clone the operator with the new operator type supplied as modification. - const operatorClone = this.layer.operator.cloneWithModifications({ - operatorType: operatorTypeClone, - }); - - // clone the layer with the new operator as modification. - const layerCloneOptions = { - operator: operatorClone, - }; - // check if layer name is identical to the current parameter display value. If true change the layer name to match the new parameter - if (this.layer.name === this.layer.operator.operatorType.getParameterDisplayValue(this.parameterName)) { - layerCloneOptions['name'] = this.parameterOptionContainer.getDisplayValueForTick(this.sliderValue); - } - - // submitt the changes to the project service. - this.projectService.changeLayer(this.layer, layerCloneOptions); - } - - ngOnInit(): void { - this.updateParameterOptions(); - } -} diff --git a/projects/wave-core/src/lib/operators/parameter-options/type-parameter-options-factory.service.ts b/projects/wave-core/src/lib/operators/parameter-options/type-parameter-options-factory.service.ts deleted file mode 100644 index bbec27d9..00000000 --- a/projects/wave-core/src/lib/operators/parameter-options/type-parameter-options-factory.service.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {OperatorTypeParameterOptions, OperatorTypeParameterOptionsConfig} from '../operator-type-parameter-options.model'; -import {GdalSourceParameterOptions, GdalSourceParameterOptionsConfig} from './gdal-source-parameter-options.model'; -import {GdalSourceType} from '../types/gdal-source-type.model'; - -/** - * A simple factory for de-serializing operator parameter options. - */ -export abstract class OperatorTypeParameterOptionsFactory { - /** - * Create operator type from serialized data. - */ - static fromDict(dict: OperatorTypeParameterOptionsConfig): OperatorTypeParameterOptions { - switch (dict.operatorType) { - case GdalSourceType.TYPE: - return GdalSourceParameterOptions.fromDict(dict as GdalSourceParameterOptionsConfig); - default: - throw Error('There is not ParameterOptions factory method defined for the "' + dict.operatorType + '" type.'); - } - } -} diff --git a/projects/wave-core/src/lib/operators/projection.model.ts b/projects/wave-core/src/lib/operators/projection.model.ts deleted file mode 100644 index 78b714db..00000000 --- a/projects/wave-core/src/lib/operators/projection.model.ts +++ /dev/null @@ -1,271 +0,0 @@ -import {get as olGetProjection, addProjection as olAddProjection, Projection as OlProjection} from 'ol/proj'; -import {register as olProj4Register} from 'ol/proj/proj4'; -import proj4 from 'proj4'; - -/** - * A wrapper class around a projection string. - */ -export abstract class Projection { - get xCoordinateName(): string { - return 'x'; - } - - get yCoordinateName(): string { - return 'y'; - } - - /** - * Create a human readable output of the projection. - * @returns The name and the code. - */ - toString(): string { - return `[${this.getCode()}] ${this.getName()}`; - } - - /** - * @return The code of the projection. - */ - abstract getCode(): string; - - /** - * @return The name of the projection. - */ - abstract getName(): string; - - /** - * @return The `ol.proj.Projection` for openlayers. - */ - getOpenlayersProjection(): OlProjection { - return olGetProjection(this.getCode()); - } - - /** - * @return The maximal extent of the projection. - */ - abstract getExtent(): [number, number, number, number]; - - /** - * @return the crs uri. - */ - abstract getCrsURI(): string; - - getProj4String(): string | undefined { - return undefined; - } -} - -export class WebMercator extends Projection { - getCode(): string { - return 'EPSG:3857'; - } - - getName(): string { - return 'WGS84 Web Mercator'; - } - - getExtent(): [number, number, number, number] { - return [-20037508.34, -20037508.34, 20037508.34, 20037508.34]; - } - - getCrsURI(): string { - return 'http://www.opengis.net/def/crs/EPSG/0/3857'; - } -} - -export class WGS84 extends Projection { - get xCoordinateName(): string { - return 'longitude'; - } - - get yCoordinateName(): string { - return 'latitude'; - } - - getCode(): string { - return 'EPSG:4326'; - } - - getName(): string { - return 'WGS 84'; - } - - getExtent(): [number, number, number, number] { - return [-180, -90, 180, 90]; - } - - getCrsURI(): string { - return 'http://www.opengis.net/def/crs/EPSG/0/4326'; - } -} - -export class UTM32N extends Projection { - getCode(): string { - return 'EPSG:32632'; - } - - getName(): string { - return 'WGS 84 / UTM 32 N'; - } - - getExtent(): [number, number, number, number] { - return [166021.4431, 0.0, 833978.5569, 9329005.1825]; - } - - getCrsURI(): string { - return 'http://www.opengis.net/def/crs/EPSG/0/32632'; - } - - getProj4String(): string | undefined { - return '+proj=utm +zone=32 +datum=WGS84 +units=m +no_defs'; - } -} - -export class ETRS89UTM32N extends Projection { - getCode(): string { - return 'EPSG:25832'; - } - - getName(): string { - return 'ETRS89 / UTM 32 N'; - } - - getExtent(): [number, number, number, number] { - return [265948.8191, 6421521.2254, 677786.3629, 7288831.7014]; - } - - getCrsURI(): string { - return 'http://www.opengis.net/def/crs/EPSG/0/25832'; - } - - getProj4String(): string | undefined { - return '+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'; - } -} - -export class GEOS extends Projection { - private static isProjectionRegistered = false; - - constructor() { - super(); - this.registerProjection(); - } - - // TODO: remove when code is correct - toString(): string { - return `[SR-ORG:81] ${this.getName()}`; - } - - getCode(): string { - // TODO: rename? - return 'SR-ORG:81'; // return 'EPSG:40453'; - } - - getName(): string { - return 'GEOS - GEOstationary Satellite'; - } - - getOpenlayersProjection() { - const projection = olGetProjection(this.getCode()); - projection.setExtent(this.getExtent()); // TODO: DT ol.proj.Projection => setExtent - return projection; - } - - getExtent(): [number, number, number, number] { - return [-5568748.276, -5568748.276, 5568748.276, 5568748.276]; - } - - getCrsURI(): string { - return 'http://spatialreference.org/ref/sr-org/81/gml/'; - } - - private registerProjection() { - if (!GEOS.isProjectionRegistered) { - olAddProjection( - new OlProjection({ - code: this.getCode(), - extent: this.getExtent(), - units: 'm', - }), - ); - - GEOS.isProjectionRegistered = true; - } - } -} - -export class ETRS89LAEA extends Projection { - getCode(): string { - return 'EPSG:3035'; - } - - getName(): string { - return 'ETRS89-LAEA'; - } - - getExtent(): [number, number, number, number] { - return [2426378.0132, 1528101.2618, 6293974.6215, 5446513.5222]; - } - - getCrsURI(): string { - return 'http://www.opengis.net/def/crs/EPSG/0/3035'; - } - - getProj4String(): string | undefined { - return '+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs'; - } -} - -export class ProjectionCollection { - static readonly INSTANCE = new ProjectionCollection(); - - WGS_84: Projection = new WGS84(); - WEB_MERCATOR: Projection = new WebMercator(); - GEOS: Projection = new GEOS(); - UTM32N: Projection = new UTM32N(); - ETRS89UTM32N: Projection = new ETRS89UTM32N(); - ERTS89LAEA: Projection = new ETRS89LAEA(); - - // required to support already stored layers - OLD_GEOS_CODE = 'EPSG:40453'; - - ALL_PROJECTIONS: Array; - - protected constructor() { - this.ALL_PROJECTIONS = [this.WGS_84, this.WEB_MERCATOR, this.GEOS, this.UTM32N, this.ETRS89UTM32N, this.ERTS89LAEA]; - this.registerProj4Projections(); - } - - fromCode(json: string) { - switch (json) { - case this.WEB_MERCATOR.getCode(): - return this.WEB_MERCATOR; - case this.WGS_84.getCode(): - return this.WGS_84; - case this.GEOS.getCode(): - return this.GEOS; - case this.OLD_GEOS_CODE: - return this.GEOS; - case this.UTM32N.getCode(): - return this.UTM32N; - case this.ETRS89UTM32N.getCode(): - return this.ETRS89UTM32N; - case this.ERTS89LAEA.getCode(): - return this.ERTS89LAEA; - default: - throw new Error('Invalid Projection String'); - } - } - - private registerProj4Projections() { - const proj4DefStrings: Array<[string, string]> = this.ALL_PROJECTIONS.filter((p) => !!p.getProj4String()).map((p) => [ - p.getCode(), - p.getProj4String(), - ]); - if (!!proj4DefStrings && proj4DefStrings.length > 0) { - proj4.defs(proj4DefStrings); - olProj4Register(proj4); - } - } -} - -export const Projections = ProjectionCollection.INSTANCE; // eslint-disable-line @typescript-eslint/naming-convention, no-underscore-dangle, id-blacklist, id-match diff --git a/projects/wave-core/src/lib/operators/result-type.model.ts b/projects/wave-core/src/lib/operators/result-type.model.ts deleted file mode 100644 index 9094608e..00000000 --- a/projects/wave-core/src/lib/operators/result-type.model.ts +++ /dev/null @@ -1,108 +0,0 @@ -/** - * Represents the result of an operator. - */ -export abstract class ResultType { - /** - * Get the mapping representtion. - */ - abstract getCode(): string; - - /** - * Human-readable form of the result type. - */ - toString(): string { - const code = this.getCode(); - return code.charAt(0).toUpperCase() + code.substring(1); - } -} - -class Raster extends ResultType { - getCode(): string { - return 'raster'; - } -} - -class Points extends ResultType { - getCode(): string { - return 'points'; - } -} - -class Lines extends ResultType { - getCode(): string { - return 'lines'; - } -} - -class Polygons extends ResultType { - getCode(): string { - return 'polygons'; - } -} - -class Plot extends ResultType { - getCode(): string { - return 'plot'; - } -} - -class Text extends ResultType { - getCode(): string { - return 'text'; - } -} - -export class ResultTypeCollection { - static readonly INSTANCE = new ResultTypeCollection(); - - RASTER: ResultType = new Raster(); - POINTS: ResultType = new Points(); - LINES: ResultType = new Lines(); - POLYGONS: ResultType = new Polygons(); - PLOT: ResultType = new Plot(); - TEXT: ResultType = new Text(); - - ALL_TYPES: Array; - INPUT_TYPES: Array; - VECTOR_TYPES: Array; - LAYER_TYPES: Array; - PLOT_TYPES: Array; - - protected constructor() { - this.ALL_TYPES = [this.RASTER, this.POINTS, this.LINES, this.POLYGONS, this.PLOT, this.TEXT]; - - this.INPUT_TYPES = [this.RASTER, this.POINTS, this.LINES, this.POLYGONS]; - - this.VECTOR_TYPES = [this.POINTS, this.LINES, this.POLYGONS]; - - this.LAYER_TYPES = [this.RASTER, this.POINTS, this.LINES, this.POLYGONS]; - - this.PLOT_TYPES = [this.PLOT, this.TEXT]; - } - - fromCode(type: string) { - switch (type.toLowerCase()) { - case this.RASTER.getCode(): - return this.RASTER; - case this.POINTS.getCode(): - case 'point': - return this.POINTS; - case 'line string': - case 'multi line string': - case this.LINES.getCode(): - return this.LINES; - case this.POLYGONS.getCode(): - case 'multi surface': - case 'multi polygon': - return this.POLYGONS; - case this.PLOT.getCode(): - return this.PLOT; - case this.TEXT.getCode(): - return this.TEXT; - default: - throw new Error('Invalid Result Type: ' + type); - } - } -} - -export const ResultTypes = ResultTypeCollection.INSTANCE; // eslint-disable-line @typescript-eslint/naming-convention, no-underscore-dangle, id-blacklist, id-match diff --git a/projects/wave-core/src/lib/operators/timeformat.model.ts b/projects/wave-core/src/lib/operators/timeformat.model.ts deleted file mode 100644 index 3f2abe58..00000000 --- a/projects/wave-core/src/lib/operators/timeformat.model.ts +++ /dev/null @@ -1,18 +0,0 @@ -class TimeFormatCollection { - ALL_FORMATS: Array<{display: string; value: string}>; - - constructor() { - this.ALL_FORMATS = [ - {display: 'yyyy-MM-ddTHH:mm:ssZ', value: '%Y-%m-%dT%H:%M:%SZ'}, - {display: 'yyyy-MM-ddTHH:mmZ', value: '%Y-%m-%dT%H:%MZ'}, - {display: 'dd-MM-yyyy HH:mm:ss', value: '%d-%m-%Y %H:%M:%S'}, - {display: 'dd.MM.yyyy HH:mm:ss', value: '%d.%m.%Y %H:%M:%S'}, - {display: 'yyyy-MM-dd HH:mm:ssZ', value: '%Y-%m-%d %H:%M:%SZ'}, - {display: 'yyyy-MM-dd HH:mmZ', value: '%Y-%m-%d %H:%MZ'}, - {display: 'dd.MM.yyyy', value: '%d.%m.%Y'}, - {display: 'yyyy-MM-dd', value: '%Y-%m-%d'}, - ]; - } -} - -export const TimeFormats = new TimeFormatCollection(); diff --git a/projects/wave-core/src/lib/operators/types/boxplot-type.model.ts b/projects/wave-core/src/lib/operators/types/boxplot-type.model.ts deleted file mode 100644 index 08cb4006..00000000 --- a/projects/wave-core/src/lib/operators/types/boxplot-type.model.ts +++ /dev/null @@ -1,152 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -import {ResultType, ResultTypes} from '../result-type.model'; - -interface BoxPlotTypeMappingDict extends OperatorTypeMappingDict { - source: string; - result: string; -} - -export interface BoxPlotTypeDict extends OperatorTypeDict { - notch: boolean; - mean: boolean; - range: number; - attributes: string[]; - inputType: string; -} - -interface BoxPlotTypeConfig { - notch: boolean; - mean: boolean; - range: number; - attributes: string[]; - inputType: ResultType; -} - -export class BoxPlotType extends OperatorType { - private static _TYPE = 'boxplot'; - private static _ICON_URL = OperatorType.createIconDataUrl(BoxPlotType._TYPE); - private static _NAME = 'Box Plot'; - - static get TYPE(): string { - return BoxPlotType._TYPE; - } - static get ICON_URL(): string { - return BoxPlotType._ICON_URL; - } - static get NAME(): string { - return BoxPlotType._NAME; - } - - private code: string; - private notch: boolean; - private mean: boolean; - private range: number; - private attributes: string[]; - private inputType: ResultType; - private resultType: ResultType; - - static fromDict(dict: BoxPlotTypeDict): BoxPlotType { - return new BoxPlotType({ - notch: dict.notch, - mean: dict.mean, - range: dict.range, - attributes: dict.attributes, - inputType: ResultTypes.fromCode(dict.inputType), - }); - } - - constructor(config: BoxPlotTypeConfig) { - super(); - this.notch = config.notch; - this.mean = config.mean; - this.range = config.range; - this.attributes = config.attributes; - this.inputType = config.inputType; - - const camelInputType = this.inputType.toString().charAt(0).toUpperCase() + this.inputType.toString().substr(1).toLowerCase(); - - this.code = ` - library(ggplot2); - - features <- mapping.load${camelInputType}(0, mapping.qrect); - - if (length(features) > 0) { - - ${this.attributes - .map((attribute, i) => { - return `dat${i} <- data.frame(group = "${attribute}", value = features$\`${attribute}\`);`; - }) - .join('\n')} - - plot.data <- rbind( - ${this.attributes.map((attribute, i) => `dat${i}`).join(', ')} - ); - - p <- ( - ggplot(plot.data, aes(x=group, y=value, fill=group)) - + geom_boxplot(notch = ${this.notch.toString().toUpperCase()}, coef = ${this.range}) - ${this.mean ? '+ stat_summary(fun.y=mean, colour="darkred", geom="point", show_guide = FALSE, shape=18, size=3)' : ''} - ${ - this.mean - ? '+ stat_summary(fun.y=mean, colour="black", geom="text", show_guide = FALSE, vjust=-0.7, aes(label=round(..y.., digits=1)))' - : '' - } - ); - - print(p); - - } else { - - plot.new(); - - mtext("Empty Dataset"); - - } - `; - // console.log(this.code); - // console.log(this.attributes); - this.resultType = ResultTypes.PLOT; - } - - getMappingName(): string { - return 'r_script'; - } - - getIconUrl(): string { - return BoxPlotType.ICON_URL; - } - - toString(): string { - return BoxPlotType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['code', this.code.toString()], - ['resultType', this.resultType.toString()], - ]; - } - - toMappingDict(): BoxPlotTypeMappingDict { - return { - source: this.code, - result: this.resultType.getCode(), - }; - } - - toDict(): BoxPlotTypeDict { - return { - operatorType: BoxPlotType.TYPE, - notch: this.notch, - mean: this.mean, - range: this.range, - attributes: this.attributes, - inputType: this.inputType.getCode(), - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return BoxPlotType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/chronicle-db-source-type.model.ts b/projects/wave-core/src/lib/operators/types/chronicle-db-source-type.model.ts deleted file mode 100644 index 686c7161..00000000 --- a/projects/wave-core/src/lib/operators/types/chronicle-db-source-type.model.ts +++ /dev/null @@ -1,155 +0,0 @@ -import {OperatorType, OperatorTypeCloneOptions, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface ChronicleDBSourceTypeConfig { - filename: string; - layer_name?: string; - query_string?: string; - time: 'none' | 'start' | 'start+end' | 'start+duration'; - duration?: number | 'inf'; - time1_format?: MappingTimeFormat; - time2_format?: MappingTimeFormat; - columns: { - x?: string; - y?: string; - time1?: string; - time2?: string; - numeric: Array; - textual: Array; - }; - default?: string; // WKT definition of default value - force_ogr_time_filter?: boolean; - on_error: 'skip' | 'abort' | 'keep'; - provenance?: { - citation: string; - license: string; - uri: string; - }; -} - -// TODO: generalize and export -interface MappingTimeFormat { - format: 'custom' | 'seconds' | 'dmyhm' | 'iso'; - custom_format?: string; -} - -interface ChronicleDBSourceTypeMappingDict extends OperatorTypeMappingDict { - filename: string; - layer_name?: string; - time: 'none' | 'start' | 'start+end' | 'start+duration'; - duration?: number | 'inf'; - time1_format?: MappingTimeFormat; - time2_format?: MappingTimeFormat; - columns: { - x?: string; - y?: string; - time1?: string; - time2?: string; - numeric: Array; - textual: Array; - }; - default?: string; // WKT definition of default value - force_ogr_time_filter?: boolean; - on_error: 'skip' | 'abort' | 'keep'; - provenance?: { - citation: string; - license: string; - uri: string; - }; -} - -export interface ChronicleDBSourceTypeDict extends OperatorTypeDict { - filename: string; - layer_name?: string; - query_string?: string; - time: 'none' | 'start' | 'start+end' | 'start+duration'; - duration?: number | 'inf'; - time1_format?: MappingTimeFormat; - time2_format?: MappingTimeFormat; - columns: { - x?: string; - y?: string; - time1?: string; - time2?: string; - numeric: Array; - textual: Array; - }; - default?: string; // WKT definition of default value - force_ogr_time_filter?: boolean; - on_error: 'skip' | 'abort' | 'keep'; - provenance?: { - citation: string; - license: string; - uri: string; - }; -} - -/** - * The raster source type. - */ -export class ChronicleDBSourceType extends OperatorType { - private static _TYPE = 'chronicle_db_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(ChronicleDBSourceType._TYPE); - private static _NAME = 'ChronicleDB Source'; - - static get TYPE(): string { - return ChronicleDBSourceType._TYPE; - } - - static get ICON_URL(): string { - return ChronicleDBSourceType._ICON_URL; - } - - static get NAME(): string { - return ChronicleDBSourceType._NAME; - } - - config: ChronicleDBSourceTypeConfig; - - static fromDict(dict: ChronicleDBSourceTypeDict): ChronicleDBSourceType { - return new ChronicleDBSourceType(dict); - } - - constructor(config: ChronicleDBSourceTypeConfig) { - super(); - this.config = config; - } - - getMappingName(): string { - return 'ogr_raw_source_with_time'; - } - - getIconUrl(): string { - return ChronicleDBSourceType.ICON_URL; - } - - toString(): string { - return ChronicleDBSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['filename', this.config.query_string ? '' : this.config.filename.toString()], // FIXME: workaround for CronicalDB - ['layer_name', this.config.layer_name ? this.config.layer_name.toString() : ''], - ['query_string', this.config.query_string ? this.config.query_string.toString() : ''], - ['columns.time1', this.config.columns.time1 ? this.config.columns.time1.toString() : ''], - ['columns.time2', this.config.columns.time2 ? this.config.columns.time2.toString() : ''], - ['columns.numeric', this.config.columns.numeric.toString()], - ['columns.textual', this.config.columns.textual.toString()], - ]; - } - - toMappingDict(): ChronicleDBSourceTypeMappingDict { - return this.config; - } - - toDict(): ChronicleDBSourceTypeDict { - return { - operatorType: ChronicleDBSourceType.TYPE, - ...this.config, - }; - } - - cloneWithModifications(options?: OperatorTypeCloneOptions): OperatorType { - return new ChronicleDBSourceType(this.config); - } -} diff --git a/projects/wave-core/src/lib/operators/types/classification-type.model.ts b/projects/wave-core/src/lib/operators/types/classification-type.model.ts deleted file mode 100644 index a926eb12..00000000 --- a/projects/wave-core/src/lib/operators/types/classification-type.model.ts +++ /dev/null @@ -1,95 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface ClassificationTypeConfig { - reclassNoData: boolean; - noDataClass: number; - remapRangeValues: Array; - remapRangeClasses: Array; -} - -interface ClassificationTypeMappingDict extends OperatorTypeMappingDict { - reclassNoData: boolean; - noDataClass: number; - RemapRange: [Array, Array]; -} - -export interface ClassificationTypeDict extends OperatorTypeDict, ClassificationTypeConfig {} - -/** - * The classification type. - */ -export class ClassificationType extends OperatorType { - private static _TYPE = 'classification'; - private static _ICON_URL = 'assets/operator-type-icons/classification.png'; - private static _NAME = 'Classification'; - - static get TYPE(): string { - return ClassificationType._TYPE; - } - static get ICON_URL(): string { - return ClassificationType._ICON_URL; - } - static get NAME(): string { - return ClassificationType._NAME; - } - - private reclassNoData: boolean; - private noDataClass: number; - private remapRangeValues: Array; - private remapRangeClasses: Array; - - constructor(config: ClassificationTypeConfig) { - super(); - this.reclassNoData = config.reclassNoData; - this.noDataClass = config.noDataClass; - this.remapRangeValues = config.remapRangeValues; - this.remapRangeClasses = config.remapRangeClasses; - } - - static fromDict(dict: ClassificationTypeDict): ClassificationType { - return new ClassificationType(dict); - } - - getMappingName(): string { - return ClassificationType.TYPE; - } - - getIconUrl(): string { - return ClassificationType.ICON_URL; - } - - toString(): string { - return ClassificationType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['reclassNoData', this.reclassNoData.toString()], - ['noDataClass', this.noDataClass.toString()], - ['values', this.remapRangeValues.toString()], - ['classes', this.remapRangeClasses.toString()], - ]; - } - - toMappingDict(): ClassificationTypeMappingDict { - return { - reclassNoData: this.reclassNoData, - noDataClass: this.noDataClass, - RemapRange: [this.remapRangeValues, this.remapRangeClasses], - }; - } - - toDict(): ClassificationTypeDict { - return { - operatorType: ClassificationType.TYPE, - reclassNoData: this.reclassNoData, - noDataClass: this.noDataClass, - remapRangeValues: this.remapRangeValues, - remapRangeClasses: this.remapRangeClasses, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return ClassificationType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/csv-source-type.model.ts b/projects/wave-core/src/lib/operators/types/csv-source-type.model.ts deleted file mode 100644 index 6c990c64..00000000 --- a/projects/wave-core/src/lib/operators/types/csv-source-type.model.ts +++ /dev/null @@ -1,210 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface CSVTimeFormat { - format: 'custom' | 'seconds' | 'dmyhm' | 'iso'; - customFormat?: string; -} - -export interface CSVParameters { - fieldSeparator: string; - geometry: 'xy' | 'wkt'; - time: 'none' | {use: 'start'; duration: number} | 'start+inf' | 'start+end' | 'start+duration'; - timeFormat?: { - time1?: CSVTimeFormat; - time2?: CSVTimeFormat; - }; - header: 0 | Array; - columns: { - x: string; - y?: string; - time1?: string; - time2?: string; - numeric: Array; - textual: Array; - }; - onError: 'skip' | 'abort' | 'keep'; - provenance?: { - citation: string; - license: string; - uri: string; - }; -} - -interface CsvSourceTypeConfig { - dataURI: string; - parameters: CSVParameters; -} - -interface MappingTimeFormat { - format: 'custom' | 'seconds' | 'dmyhm' | 'iso'; - custom_format?: string; -} -interface CsvSourceTypeMappingDict extends OperatorTypeMappingDict { - filename: string; - separator: string; - geometry: 'xy' | 'wkt'; - time: 'none' | 'start' | 'start+end' | 'start+duration'; - duration?: number | 'inf'; - time1_format?: MappingTimeFormat; - time2_format?: MappingTimeFormat; - columns: { - x: string; - y?: string; - time1?: string; - time2?: string; - numeric: Array; - textual: Array; - }; - on_error: 'skip' | 'abort' | 'keep'; - provenance?: { - citation: string; - license: string; - uri: string; - }; -} - -export interface CsvSourceTypeDict extends OperatorTypeDict { - dataURI: string; - parameters: CSVParameters; -} - -/** - * The CSV source type. - */ -export class CsvSourceType extends OperatorType { - private static _TYPE = 'csv_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(CsvSourceType._TYPE); - private static _NAME = 'CSV Source'; - - static get TYPE(): string { - return CsvSourceType._TYPE; - } - - static get ICON_URL(): string { - return CsvSourceType._ICON_URL; - } - - static get NAME(): string { - return CsvSourceType._NAME; - } - - private dataURI: string; - private parameters: CSVParameters; - - static fromDict(dict: CsvSourceTypeDict): CsvSourceType { - return new CsvSourceType({ - dataURI: dict.dataURI, - parameters: dict.parameters, - }); - } - - constructor(config: CsvSourceTypeConfig) { - super(); - this.dataURI = config.dataURI; - this.parameters = config.parameters; - } - - getMappingName(): string { - return CsvSourceType.TYPE; - } - - getIconUrl(): string { - return CsvSourceType.ICON_URL; - } - - toString(): string { - return CsvSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['dataURI', this.dataURI], - ['geometry', this.parameters.geometry], - ['fieldSeparator', this.parameters.fieldSeparator], - ['time', this.parameters.time ? JSON.stringify(this.parameters.time) : ''], - ]; - } - - toMappingDict(): CsvSourceTypeMappingDict { - let data = this.dataURI; - if (Array.isArray(this.parameters.header)) { - if (data.indexOf('data:') === 0) { - const commaPosition = data.indexOf(','); - const uriPart = data.substring(0, commaPosition + 1); - const dataPart = data.substring(commaPosition + 1, data.length); - - const headerPart = (this.parameters.header as Array).join(this.parameters.fieldSeparator) + '\n'; - - data = uriPart + headerPart + dataPart; - } - } - - let dict: CsvSourceTypeMappingDict = { - filename: data, - separator: this.parameters.fieldSeparator, - geometry: this.parameters.geometry, - on_error: this.parameters.onError, - time: 'none', - columns: { - x: this.parameters.columns.x, - numeric: this.parameters.columns.numeric, - textual: this.parameters.columns.textual, - }, - }; - - if (this.parameters.time === 'start+inf') { - dict.time = 'start'; - dict.duration = 'inf'; - } else if (typeof this.parameters.time !== 'string') { - const startPlusDuration = this.parameters.time as {use: string; duration: number}; - dict.time = 'start'; - dict.duration = startPlusDuration.duration; - } else { - dict.time = this.parameters.time; - } - - if (this.parameters.time !== 'none') { - dict.time1_format = { - format: this.parameters.timeFormat.time1.format, - }; - if (this.parameters.timeFormat.time1.format === 'custom') { - dict.time1_format.custom_format = this.parameters.timeFormat.time1.customFormat; - } - - dict.columns.time1 = this.parameters.columns.time1; - - if (this.parameters.timeFormat.time2) { - dict.time2_format = { - format: this.parameters.timeFormat.time2.format, - }; - if (this.parameters.timeFormat.time2.format === 'custom') { - dict.time2_format.custom_format = this.parameters.timeFormat.time2.customFormat; - } - - dict.columns.time2 = this.parameters.columns.time2; - } - } - - if (this.parameters.geometry !== 'wkt') { - dict.columns.y = this.parameters.columns.y; - } - - if (this.parameters.provenance) { - dict.provenance = this.parameters.provenance; - } - - return dict; - } - - toDict(): CsvSourceTypeDict { - return { - operatorType: CsvSourceType.TYPE, - dataURI: this.dataURI, - parameters: this.parameters, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return CsvSourceType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/expression-type.model.ts b/projects/wave-core/src/lib/operators/types/expression-type.model.ts deleted file mode 100644 index 94232a31..00000000 --- a/projects/wave-core/src/lib/operators/types/expression-type.model.ts +++ /dev/null @@ -1,107 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -import {Unit, UnitDict, UnitMappingDict} from '../unit.model'; -import {DataType, DataTypes} from '../datatype.model'; - -/** - * The expression specifies calculations between the rasters. - * There must be a valid data type and unit for the resulting raster. - */ -interface ExpressionTypeConfig { - expression: string; - datatype: DataType; - unit: Unit; -} - -interface ExpressionTypeMappingDict extends OperatorTypeMappingDict { - expression: string; - datatype: string; - unit: UnitMappingDict; -} - -export interface ExpressionTypeDict extends OperatorTypeDict { - expression: string; - datatype: string; - unit: UnitDict; -} - -/** - * The expression type. - */ -export class ExpressionType extends OperatorType { - private static _TYPE = 'expression'; - private static _ICON_URL = 'assets/operator-type-icons/expression.png'; - private static _NAME = 'Expression'; - - static get TYPE(): string { - return ExpressionType._TYPE; - } - - static get ICON_URL(): string { - return ExpressionType._ICON_URL; - } - - static get NAME(): string { - return ExpressionType._NAME; - } - - private expression: string; - private datatype: DataType; - private unit: Unit; - - constructor(config: ExpressionTypeConfig) { - super(); - this.expression = config.expression; - this.datatype = config.datatype; - this.unit = config.unit; - } - - static fromDict(dict: ExpressionTypeDict): ExpressionType { - return new ExpressionType({ - expression: dict.expression, - datatype: DataTypes.fromCode(dict.datatype), - unit: Unit.fromDict(dict.unit), - }); - } - - getMappingName(): string { - return ExpressionType.TYPE; - } - - getIconUrl(): string { - return ExpressionType.ICON_URL; - } - - toString(): string { - return ExpressionType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['expression', this.expression.toString()], - ['datatype', this.datatype.toString()], - ['unit', this.unit.toString()], - ]; - } - - toMappingDict(): ExpressionTypeMappingDict { - return { - expression: this.expression, - datatype: this.datatype.getCode(), - unit: this.unit.toMappingDict(), - }; - } - - toDict(): ExpressionTypeDict { - return { - operatorType: ExpressionType.TYPE, - expression: this.expression, - datatype: this.datatype.getCode(), - unit: this.unit.toDict(), - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return ExpressionType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/feature-collection-db-source-type.model.ts b/projects/wave-core/src/lib/operators/types/feature-collection-db-source-type.model.ts deleted file mode 100644 index db4d4823..00000000 --- a/projects/wave-core/src/lib/operators/types/feature-collection-db-source-type.model.ts +++ /dev/null @@ -1,89 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface FeatureCollectionDBSourceTypeConfig { - owner: string; - data_set_name: string; -} - -interface FeatureCollectionDBSourceTypeMappingDict extends OperatorTypeMappingDict { - owner: string; - data_set_name: string; -} - -export interface FeatureCollectionDBSourceTypeDict extends OperatorTypeDict { - owner: string; - data_set_name: string; -} - -/** - * The FeatureCollectionDB source type. - */ -export class FeatureCollectionDBSourceType extends OperatorType { - private static _TYPE = 'featurecollectiondb_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(FeatureCollectionDBSourceType._TYPE); - private static _NAME = 'Feature Collection DB Source'; - - static get TYPE(): string { - return FeatureCollectionDBSourceType._TYPE; - } - static get ICON_URL(): string { - return FeatureCollectionDBSourceType._ICON_URL; - } - static get NAME(): string { - return FeatureCollectionDBSourceType._NAME; - } - - private owner: string; - private data_set_name: string; - - static fromDict(dict: FeatureCollectionDBSourceTypeDict): FeatureCollectionDBSourceType { - return new FeatureCollectionDBSourceType({ - owner: dict.owner, - data_set_name: dict.data_set_name, - }); - } - - constructor(config: FeatureCollectionDBSourceTypeConfig) { - super(); - this.owner = config.owner; - this.data_set_name = config.data_set_name; - } - - getMappingName(): string { - return FeatureCollectionDBSourceType.TYPE; - } - - getIconUrl(): string { - return FeatureCollectionDBSourceType.ICON_URL; - } - - toString(): string { - return FeatureCollectionDBSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['owner', this.owner], - ['data_set_name', this.data_set_name], - ]; - } - - toMappingDict(): FeatureCollectionDBSourceTypeMappingDict { - return { - owner: this.owner, - data_set_name: this.data_set_name, - }; - } - - toDict(): FeatureCollectionDBSourceTypeDict { - return { - operatorType: FeatureCollectionDBSourceType.TYPE, - owner: this.owner, - data_set_name: this.data_set_name, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return FeatureCollectionDBSourceType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/gdal-source-type.model.ts b/projects/wave-core/src/lib/operators/types/gdal-source-type.model.ts deleted file mode 100644 index 46584428..00000000 --- a/projects/wave-core/src/lib/operators/types/gdal-source-type.model.ts +++ /dev/null @@ -1,304 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; -import {Unit, UnitDict, UnitMappingDict} from '../unit.model'; -import {GdalSourceChannelOptions} from '../parameter-options/gdal-source-parameter-options.model'; -import {MappingRasterMethodology} from '../dialogs/data-repository/mapping-source.model'; - -/** - * The interface for gdal source requests - */ -interface GdalSourceTypeConfig { - channel?: number; // required for old configs - channelConfig: GdalSourceChannelOptions; // FIXME: this should be the interface from gdal-source-parameter-options! - sourcename: string; - transform: boolean; - gdal_params?: GdalParamsType; -} - -/** - * Options allowed to replace when cloning. - */ -export interface GdalSourceTypeCloneOptions { - channelConfig: GdalSourceChannelOptions; -} - -/** - * Representation send to mapping when requesting gdal source data. - */ -interface GdalSourceTypeMappingDict extends OperatorTypeMappingDict { - channel: number; - sourcename: string; - transform: boolean; - gdal_params?: GdalParamsTypeMappingDict; -} - -/** - * Serianlization interface. - */ -export interface GdalSourceTypeDict extends OperatorTypeDict { - channelConfig: GdalSourceChannelOptions; - sourcename: string; - transform: boolean; - gdal_params?: GdalParamsTypeDict; -} - -/** - * The gdal raster source type. - */ -export class GdalSourceType extends OperatorType { - private static _TYPE = 'gdal_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(GdalSourceType._TYPE); - private static _NAME = 'GDAL Source'; - - static get TYPE(): string { - return GdalSourceType._TYPE; - } - - static get ICON_URL(): string { - return GdalSourceType._ICON_URL; - } - - static get NAME(): string { - return GdalSourceType._NAME; - } - - private channelConfig: GdalSourceChannelOptions; - private sourcename: string; - private transform: boolean; - private gdalParams: GdalParamsType = undefined; - - /** - * Deserialization - */ - static fromDict(dict: GdalSourceTypeDict): GdalSourceType { - return new GdalSourceType({ - channel: dict['channel'], // old configs - channelConfig: dict.channelConfig, - gdal_params: dict.gdal_params - ? { - channels: dict.gdal_params.channels - ? dict.gdal_params.channels.map((channelDict) => { - return { - channel: channelDict.channel, - datatype: channelDict.datatype, - file_name: channelDict.file_name, - path: channelDict.path, - unit: Unit.fromDict(channelDict.unit), - netcdf_subdataset: channelDict.netcdf_subdataset, - }; - }) - : undefined, - file_name: dict.gdal_params.file_name, - path: dict.gdal_params.path, - coords: dict.gdal_params.coords, - provenance: dict.gdal_params.provenance, - netcdf_subdataset: dict.gdal_params.netcdf_subdataset, - time_start: dict.gdal_params.time_start, - time_end: dict.gdal_params.time_end, - channel_start_time_list: dict.gdal_params.channel_start_time_list, - } - : undefined, - sourcename: dict.sourcename, - transform: dict.transform, - }); - } - - constructor(config: GdalSourceTypeConfig) { - super(); - this.channelConfig = config.channelConfig - ? config.channelConfig - : {displayValue: 'channel number ' + config.channel, channelNumber: config.channel}; // convert old configs - this.sourcename = config.sourcename; - this.transform = config.transform; - this.gdalParams = config.gdal_params; - } - - getMappingName(): string { - return GdalSourceType.TYPE; - } - - getIconUrl(): string { - return GdalSourceType.ICON_URL; - } - - toString(): string { - return GdalSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['channelConfig', this.channelConfig.displayValue.toString()], - ['sourcename', this.sourcename.toString()], - ['transform', this.transform.toString()], - ]; - } - - getParameterValue(parameterName: string): GdalSourceChannelOptions | undefined { - switch (parameterName) { - case 'channelConfig': - return this.channelConfig; - default: - return undefined; - } - } - - toMappingDict(): GdalSourceTypeMappingDict { - return { - sourcename: this.sourcename, - channel: this.channelConfig.channelNumber, - transform: this.transform, - gdal_params: this.gdalParams - ? { - channels: this.gdalParams.channels - ? this.gdalParams.channels.map((channelDict, i) => { - if (this.channelConfig.channelNumber !== i) { - return undefined; - } - return { - channel: channelDict.channel, - datatype: channelDict.datatype, - file_name: channelDict.file_name, - path: channelDict.path, - unit: channelDict.unit.toMappingDict(), - netcdf_subdataset: channelDict.netcdf_subdataset, - }; - }) - : undefined, - file_name: this.gdalParams.file_name, - path: this.gdalParams.path, - netcdf_subdataset: this.gdalParams.netcdf_subdataset, - coords: this.gdalParams.coords, - provenance: this.gdalParams.provenance, - time_start: this.gdalParams.time_start, - time_end: this.gdalParams.time_end, - channel_start_time_list: this.gdalParams.channel_start_time_list, - } - : undefined, - }; - } - - toDict(): GdalSourceTypeDict { - return { - operatorType: GdalSourceType.TYPE, - sourcename: this.sourcename, - channelConfig: this.channelConfig, - transform: this.transform, - gdal_params: this.gdalParams - ? { - channels: this.gdalParams.channels - ? this.gdalParams.channels.map((channelDict) => { - return { - channel: channelDict.channel, - datatype: channelDict.datatype, - file_name: channelDict.file_name, - path: channelDict.path, - unit: channelDict.unit.toDict(), - netcdf_subdataset: channelDict.netcdf_subdataset, - }; - }) - : undefined, - file_name: this.gdalParams.file_name, - path: this.gdalParams.path, - netcdf_subdataset: this.gdalParams.netcdf_subdataset, - coords: this.gdalParams.coords, - provenance: this.gdalParams.provenance, - time_start: this.gdalParams.time_start, - time_end: this.gdalParams.time_end, - channel_start_time_list: this.gdalParams.channel_start_time_list, - } - : undefined, - }; - } - - cloneWithModifications(options?: GdalSourceTypeCloneOptions): OperatorType { - return new GdalSourceType({ - channelConfig: options && options.channelConfig ? options.channelConfig : this.channelConfig, - sourcename: this.sourcename, - transform: this.transform, - gdal_params: this.gdalParams ? this.gdalParams : undefined, - }); - } -} - -/** - * This interface allows to specify all gedal source params (replaces json file in MAPPING). - */ -export interface GdalParamsType { - channels: Array<{ - channel: number; - datatype: string; - file_name?: string; - path?: string; - unit: Unit; - netcdf_subdataset?: string; - }>; - netcdf_subdataset?: string; - file_name?: string; - path?: string; - coords: { - crs: string; - }; - channel_start_time_list?: Array; - time_start?: string; - time_end?: string; - provenance: { - citation: string; - license: string; - uri: string; - }; -} - -/** - * Serialization for GdalParamsType. - */ -export interface GdalParamsTypeDict { - channels: Array<{ - channel: number; - datatype: string; - file_name?: string; - path?: string; - unit: UnitDict; - netcdf_subdataset?: string; - }>; - netcdf_subdataset?: string; - file_name?: string; - path?: string; - coords: { - crs: string; - }; - channel_start_time_list?: Array; - time_start?: string; - time_end?: string; - provenance: { - citation: string; - license: string; - uri: string; - }; -} - -/** - * Serialization of GdalParamsType for mapping. - */ -export interface GdalParamsTypeMappingDict { - channels: Array<{ - channel: number; - datatype: string; - file_name?: string; - path?: string; - unit: UnitMappingDict; - netcdf_subdataset?: string; - }>; - file_name?: string; - netcdf_subdataset?: string; - path?: string; - coords: { - crs: string; - }; - channel_start_time_list?: Array; - time_start?: string; - time_end?: string; - provenance: { - citation: string; - license: string; - uri: string; - }; -} diff --git a/projects/wave-core/src/lib/operators/types/gfbio-source-type.model.ts b/projects/wave-core/src/lib/operators/types/gfbio-source-type.model.ts deleted file mode 100644 index 980c39bc..00000000 --- a/projects/wave-core/src/lib/operators/types/gfbio-source-type.model.ts +++ /dev/null @@ -1,117 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -export interface BasicColumns { - numeric: Array; - textual: Array; -} - -interface GFBioSourceTypeConfig { - dataSource: string; - level: string; // family, genus, species - term: string; - columns: BasicColumns; -} - -interface GFBioSourceTypeMappingDict extends OperatorTypeMappingDict { - dataSource: string; - level: string; - term: string; - columns: BasicColumns; -} - -export interface GFBioSourceTypeDict extends OperatorTypeDict { - dataSource: string; - level: string; - term: string; - columns: BasicColumns; - scientificName?: string; // FIXME: legacy support -} - -/** - * The GFBio source type. - */ -export class GFBioSourceType extends OperatorType { - private static _TYPE = 'gfbio_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(GFBioSourceType._TYPE); - private static _NAME = 'GFBio Source'; - - static get TYPE(): string { - return GFBioSourceType._TYPE; - } - - static get ICON_URL(): string { - return GFBioSourceType._ICON_URL; - } - - static get NAME(): string { - return GFBioSourceType._NAME; - } - - private dataSource: string; - private level: string; - private term: string; - private columns: BasicColumns; - - constructor(config: GFBioSourceTypeConfig) { - super(); - this.dataSource = config.dataSource; - this.level = config.level; - this.term = config.term; - this.columns = config.columns; - } - - static fromDict(dict: GFBioSourceTypeDict): GFBioSourceType { - return new GFBioSourceType({ - dataSource: dict.dataSource, - level: dict.level ? dict.level : 'species', - term: dict.term ? dict.term : dict.scientificName, - columns: dict.columns, - }); - } - - getMappingName(): string { - return GFBioSourceType.TYPE; - } - - getIconUrl(): string { - return GFBioSourceType.ICON_URL; - } - - toString(): string { - return GFBioSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - const columns = this.columns.numeric.concat(this.columns.textual); - columns.sort(); - return [ - ['dataSource', this.dataSource.toString()], - ['level', this.level.toString()], - ['term', this.term.toString()], - ['columns', columns.join(', ')], - ]; - } - - toMappingDict(): GFBioSourceTypeMappingDict { - return { - dataSource: this.dataSource, - level: this.level, - term: this.term, - columns: this.columns, - }; - } - - toDict(): GFBioSourceTypeDict { - return { - operatorType: GFBioSourceType.TYPE, - dataSource: this.dataSource, - level: this.level, - term: this.term, - columns: this.columns, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return GFBioSourceType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/heatmap-type.model.ts b/projects/wave-core/src/lib/operators/types/heatmap-type.model.ts deleted file mode 100644 index 16ea4ff3..00000000 --- a/projects/wave-core/src/lib/operators/types/heatmap-type.model.ts +++ /dev/null @@ -1,91 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface HeatmapTypeConfig { - attribute: string; - radius: number; -} - -interface HeatmapTypeMappingDict extends OperatorTypeMappingDict { - attribute: string; - radius: number; -} - -export interface HeatmapTypeDict extends OperatorTypeDict { - attribute: string; - radius: number; -} - -/** - * The heatmap type. - */ -export class HeatmapType extends OperatorType { - private static _TYPE = 'rasterization'; - private static _ICON_URL = OperatorType.createIconDataUrl(HeatmapType._TYPE); - private static _NAME = 'Heatmap'; - - private attribute: string; - private radius: number; - - static fromDict(dict: HeatmapTypeDict): HeatmapType { - return new HeatmapType({ - attribute: dict.attribute, - radius: dict.radius, - }); - } - - constructor(config: HeatmapTypeConfig) { - super(); - this.attribute = config.attribute; - this.radius = config.radius; - } - - static get TYPE(): string { - return HeatmapType._TYPE; - } - - static get ICON_URL(): string { - return HeatmapType._ICON_URL; - } - - static get NAME(): string { - return HeatmapType._NAME; - } - - getMappingName(): string { - return HeatmapType.TYPE; - } - - getIconUrl(): string { - return HeatmapType.ICON_URL; - } - - toString(): string { - return HeatmapType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['attribute', this.attribute.toString()], - ['radius', this.radius.toString()], - ]; - } - - toMappingDict(): HeatmapTypeMappingDict { - return { - attribute: this.attribute, - radius: this.radius, - }; - } - - toDict(): HeatmapTypeDict { - return { - operatorType: HeatmapType.TYPE, - attribute: this.attribute, - radius: this.radius, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return HeatmapType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/histogram-type.model.ts b/projects/wave-core/src/lib/operators/types/histogram-type.model.ts deleted file mode 100644 index c890c5cf..00000000 --- a/projects/wave-core/src/lib/operators/types/histogram-type.model.ts +++ /dev/null @@ -1,117 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface HistogramTypeMappingDict extends OperatorTypeMappingDict { - attribute: string; - range: [number, number] | string; // `[min, max]` or `unit` or `data` - buckets?: number; -} - -export interface HistogramTypeDict extends OperatorTypeDict { - attribute: string; - range: {min: number; max: number} | string; - buckets?: number; -} - -/** - * The histogram is defined for one attribute of the input layer. - * The range and buckets specify the resulting histogram. - * If no number of buckets is specified, it uses suitable defaults. - */ -interface HistogramTypeConfig { - attribute: string; - range: {min: number; max: number} | string; - buckets?: number; -} - -/** - * The histogram type. - */ -export class HistogramType extends OperatorType { - private static _TYPE = 'histogram'; - private static _ICON_URL = OperatorType.createIconDataUrl(HistogramType._TYPE); - private static _NAME = 'Histogram'; - - static get TYPE(): string { - return HistogramType._TYPE; - } - - static get ICON_URL(): string { - return HistogramType._ICON_URL; - } - - static get NAME(): string { - return HistogramType._NAME; - } - - private attribute: string; - private range: {min: number; max: number} | string; - private buckets: number; - - constructor(config: HistogramTypeConfig) { - super(); - this.attribute = config.attribute; - this.range = config.range; - this.buckets = config.buckets; - } - - static fromDict(dict: HistogramTypeDict): HistogramType { - return new HistogramType(dict); - } - - getMappingName(): string { - return HistogramType.TYPE; - } - - getIconUrl(): string { - return HistogramType.ICON_URL; - } - - toString(): string { - return HistogramType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - let range: string; - if (typeof this.range === 'string') { - range = this.range as string; - } else { - const rangeStruct = this.range as {min: number; max: number}; - range = `min: ${rangeStruct.min}, max: ${rangeStruct.max}`; - } - - return [ - ['attribute', this.attribute.toString()], - ['range', range], - ['buckets', this.buckets.toString()], - ]; - } - - toMappingDict(): HistogramTypeMappingDict { - let range: [number, number] | string; - if (typeof this.range === 'string') { - range = this.range as string; - } else { - const rangeStruct = this.range as {min: number; max: number}; - range = [rangeStruct.min, rangeStruct.max]; - } - - return { - attribute: this.attribute, - range: range, - buckets: this.buckets, - }; - } - - toDict(): HistogramTypeDict { - return { - operatorType: HistogramType.TYPE, - attribute: this.attribute, - range: this.range, - buckets: this.buckets, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return HistogramType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/msg-types.model.ts b/projects/wave-core/src/lib/operators/types/msg-types.model.ts deleted file mode 100644 index af03ec10..00000000 --- a/projects/wave-core/src/lib/operators/types/msg-types.model.ts +++ /dev/null @@ -1,480 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -/** - * The MSG radiance type. - */ -export class MsgRadianceType extends OperatorType { - private static _TYPE = 'meteosat_radiance'; - private static _ICON_URL = OperatorType.createIconDataUrl(MsgRadianceType._TYPE); - private static _NAME = 'MSG Radiance Operator'; - - static get TYPE(): string { - return MsgRadianceType._TYPE; - } - - static get ICON_URL(): string { - return MsgRadianceType._ICON_URL; - } - - static get NAME(): string { - return MsgRadianceType._NAME; - } - - constructor(config: {}) { - super(); - } - - static fromDict(dict: OperatorTypeDict): MsgRadianceType { - return new MsgRadianceType({}); - } - - getMappingName(): string { - return MsgRadianceType.TYPE; - } - - getIconUrl(): string { - return MsgRadianceType.ICON_URL; - } - - toString(): string { - return MsgRadianceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return []; - } - - toMappingDict(): OperatorTypeMappingDict { - return {}; - } - - toDict(): OperatorTypeDict { - return { - operatorType: MsgRadianceType.TYPE, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return MsgRadianceType.fromDict(this.toDict()); // TODO: add modifications - } -} - -/* The MSG reflectance type */ -interface MsgReflectanceTypeMappingDict extends OperatorTypeMappingDict { - isHrv: boolean; - solarCorrection: boolean; - forceSatellite?: MeteosatSatelliteName; -} - -export interface MsgReflectanceTypeDict extends OperatorTypeDict { - isHrv: boolean; - solarCorrection: boolean; - forceSatelliteName?: MeteosatSatelliteName; -} - -interface MsgReflectanceTypeConfig { - isHrv: boolean; - solarCorrection: boolean; - forceSatelliteName?: MeteosatSatelliteName; -} - -export type MeteosatSatelliteName = 'Meteosat-8' | 'Meteosat-9' | 'Meteosat-10' | 'Meteosat-11'; - -/** - * The MSG radiance type. - */ -export class MsgReflectanceType extends OperatorType { - private static _TYPE = 'meteosat_reflectance'; - private static _ICON_URL = OperatorType.createIconDataUrl(MsgReflectanceType._TYPE); - private static _NAME = 'MSG Reflectance Operator'; - - static get TYPE(): string { - return MsgReflectanceType._TYPE; - } - static get ICON_URL(): string { - return MsgReflectanceType._ICON_URL; - } - static get NAME(): string { - return MsgReflectanceType._NAME; - } - - private isHrv: boolean = false; - private solarCorrection: boolean = true; - private forceSatelliteName: MeteosatSatelliteName = undefined; - private forceSatellite: boolean = false; - - constructor(config: MsgReflectanceTypeConfig) { - super(); - this.isHrv = config.isHrv; - this.solarCorrection = config.solarCorrection; - if (config.forceSatelliteName) { - this.forceSatelliteName = config.forceSatelliteName; - } - this.forceSatellite = this.forceSatelliteName !== undefined; - } - - static fromDict(dict: MsgReflectanceTypeDict): MsgReflectanceType { - return new MsgReflectanceType(dict); - } - - getMappingName(): string { - return MsgReflectanceType.TYPE; - } - - getIconUrl(): string { - return MsgReflectanceType.ICON_URL; - } - - toString(): string { - return MsgReflectanceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return []; - } - - toMappingDict(): MsgReflectanceTypeMappingDict { - const config: MsgReflectanceTypeMappingDict = { - isHrv: this.isHrv, - solarCorrection: this.solarCorrection, - }; - if (this.forceSatellite && this.forceSatelliteName) { - config.forceSatellite = this.forceSatelliteName; - } - return config; - } - - toDict(): MsgReflectanceTypeDict { - let dict: MsgReflectanceTypeDict = { - operatorType: MsgReflectanceType.TYPE, - isHrv: this.isHrv, - solarCorrection: this.solarCorrection, - }; - if (this.forceSatellite && this.forceSatelliteName) { - dict['forceSatelliteName'] = this.forceSatelliteName; - } - return dict; - } - - cloneWithModifications(options?: {}): OperatorType { - return MsgRadianceType.fromDict(this.toDict()); // TODO: add modifications - } -} - -/* The MSG solarangle type */ -interface MsgSolarangleTypeMappingDict extends OperatorTypeMappingDict { - solarangle: string; -} - -export interface MsgSolarangleTypeDict extends OperatorTypeDict { - solarangle: SolarangleName; -} - -interface MsgSolarangleTypeConfig { - solarangle: SolarangleName; -} - -export type SolarangleName = 'azimuth' | 'zenith'; - -/** - * The MSG solarangle type. - */ -export class MsgSolarangleType extends OperatorType { - private static _TYPE = 'meteosat_solar_angle'; - private static _ICON_URL = OperatorType.createIconDataUrl(MsgSolarangleType._TYPE); - private static _NAME = 'MSG Solarangle Operator'; - - static get TYPE(): string { - return MsgSolarangleType._TYPE; - } - static get ICON_URL(): string { - return MsgSolarangleType._ICON_URL; - } - static get NAME(): string { - return MsgSolarangleType._NAME; - } - - private solarangle: SolarangleName; - - constructor(config: MsgSolarangleTypeConfig) { - super(); - this.solarangle = config.solarangle; - } - - static fromDict(dict: MsgSolarangleTypeDict): MsgRadianceType { - return new MsgRadianceType(dict); - } - - getMappingName(): string { - return MsgSolarangleType.TYPE; - } - - getIconUrl(): string { - return MsgSolarangleType.ICON_URL; - } - - toString(): string { - return MsgSolarangleType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return []; - } - - toMappingDict(): MsgSolarangleTypeMappingDict { - return { - solarangle: this.solarangle, - }; - } - - toDict(): MsgSolarangleTypeDict { - return { - operatorType: MsgSolarangleType.TYPE, - solarangle: this.solarangle, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return MsgSolarangleType.fromDict(this.toDict()); // TODO: add modifications - } -} - -/** - * The MSG temperature type. - */ -export class MsgTemperatureType extends OperatorType { - private static _TYPE = 'meteosat_temperature'; - private static _ICON_URL = OperatorType.createIconDataUrl(MsgTemperatureType._TYPE); - private static _NAME = 'MSG Temperature Operator'; - - static get TYPE(): string { - return MsgTemperatureType._TYPE; - } - - static get ICON_URL(): string { - return MsgTemperatureType._ICON_URL; - } - - static get NAME(): string { - return MsgTemperatureType._NAME; - } - - constructor(config: {}) { - super(); - } - - static fromDict(dict: OperatorTypeDict): MsgTemperatureType { - return new MsgTemperatureType(dict); - } - - getMappingName(): string { - return MsgTemperatureType.TYPE; - } - - getIconUrl(): string { - return MsgTemperatureType.ICON_URL; - } - - toString(): string { - return MsgTemperatureType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return []; - } - - toMappingDict(): OperatorTypeMappingDict { - return {}; - } - - toDict(): OperatorTypeDict { - return { - operatorType: MsgTemperatureType.TYPE, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return MsgTemperatureType.fromDict(this.toDict()); // TODO: add modifications - } -} - -/* The MSG pansharpen type */ -interface MsgPansharpenTypeMappingDict extends OperatorTypeMappingDict {} - -export interface MsgPansharpenTypeDict extends OperatorTypeDict {} - -interface MsgPansharpenTypeConfig {} - -/** - * The MSG pansharpen type. - */ -export class MsgPansharpenType extends OperatorType { - private static _TYPE = 'meteosat_pansharpening'; - private static _ICON_URL = OperatorType.createIconDataUrl(MsgPansharpenType._TYPE); - private static _NAME = 'MSG Pansharpen Operator'; - - static get TYPE(): string { - return MsgPansharpenType._TYPE; - } - - static get ICON_URL(): string { - return MsgPansharpenType._ICON_URL; - } - - static get NAME(): string { - return MsgPansharpenType._NAME; - } - - constructor(config: MsgPansharpenTypeConfig) { - super(); - } - - static fromDict(dict: MsgPansharpenTypeDict): MsgPansharpenType { - return new MsgPansharpenType(dict); - } - - getMappingName(): string { - return MsgPansharpenType.TYPE; - } - - getIconUrl(): string { - return MsgPansharpenType.ICON_URL; - } - - toString(): string { - return MsgPansharpenType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return []; - } - - toMappingDict(): MsgPansharpenTypeMappingDict { - return {}; - } - - toDict(): MsgPansharpenTypeDict { - return { - operatorType: MsgPansharpenType.TYPE, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return MsgPansharpenType.fromDict(this.toDict()); // TODO: add modifications - } -} - -/** - * The MSG temperature type. - */ -export class MsgCo2CorrectionType extends OperatorType { - private static _TYPE = 'meteosat_co2correction'; - private static _ICON_URL = OperatorType.createIconDataUrl(MsgCo2CorrectionType._TYPE); - private static _NAME = 'MSG CO2 Correction Operator'; - - static get TYPE(): string { - return MsgCo2CorrectionType._TYPE; - } - - static get ICON_URL(): string { - return MsgCo2CorrectionType._ICON_URL; - } - - static get NAME(): string { - return MsgCo2CorrectionType._NAME; - } - - constructor(config: {}) { - super(); - } - - static fromDict(dict: OperatorTypeDict): MsgCo2CorrectionType { - return new MsgCo2CorrectionType(dict); - } - - getMappingName(): string { - return MsgCo2CorrectionType.TYPE; - } - - getIconUrl(): string { - return MsgCo2CorrectionType.ICON_URL; - } - - toString(): string { - return MsgCo2CorrectionType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return []; - } - - toMappingDict(): OperatorTypeMappingDict { - return {}; - } - - toDict(): OperatorTypeDict { - return { - operatorType: MsgCo2CorrectionType.TYPE, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return MsgCo2CorrectionType.fromDict(this.toDict()); // TODO: add modifications - } -} - -export class MsgSofosGccThermalThresholdType extends OperatorType { - private static _TYPE = 'meteosat_gccthermthresholddetection'; - private static _ICON_URL = OperatorType.createIconDataUrl(MsgSofosGccThermalThresholdType._TYPE); - private static _NAME = 'MSG SOFOS thermal threshold detection operator'; - - static get TYPE(): string { - return MsgSofosGccThermalThresholdType._TYPE; - } - - static get ICON_URL(): string { - return MsgSofosGccThermalThresholdType._ICON_URL; - } - - static get NAME(): string { - return MsgSofosGccThermalThresholdType._NAME; - } - - constructor(config: {}) { - super(); - } - - static fromDict(dict: OperatorTypeDict): MsgSofosGccThermalThresholdType { - return new MsgSofosGccThermalThresholdType(dict); - } - - getMappingName(): string { - return MsgSofosGccThermalThresholdType.TYPE; - } - - getIconUrl(): string { - return MsgSofosGccThermalThresholdType.ICON_URL; - } - - toString(): string { - return MsgSofosGccThermalThresholdType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return []; - } - - toMappingDict(): OperatorTypeMappingDict { - return {}; - } - - toDict(): OperatorTypeDict { - return { - operatorType: MsgSofosGccThermalThresholdType.TYPE, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return MsgSofosGccThermalThresholdType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/numeric-attribute-filter-type.model.ts b/projects/wave-core/src/lib/operators/types/numeric-attribute-filter-type.model.ts deleted file mode 100644 index e5f2dc08..00000000 --- a/projects/wave-core/src/lib/operators/types/numeric-attribute-filter-type.model.ts +++ /dev/null @@ -1,104 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface NumericAttributeFilterTypeMappingDict extends OperatorTypeMappingDict { - name: string; - includeNoData: boolean; - rangeMin?: number; - rangeMax?: number; -} - -export interface NumericAttributeFilterTypeDict extends OperatorTypeDict { - attributeName: string; - includeNoData: boolean; - rangeMin?: number; - rangeMax?: number; -} - -interface NumericAttributeFilterTypeConfig { - attributeName: string; - includeNoData: boolean; - rangeMin?: number; - rangeMax?: number; -} - -/** - * The numeric attribute filter type. - */ -export class NumericAttributeFilterType extends OperatorType { - private static _TYPE = 'numeric_attribute_filter'; - private static _ICON_URL = OperatorType.createIconDataUrl(NumericAttributeFilterType._TYPE); - private static _NAME = 'Numeric Attribute Filter'; - - static get TYPE(): string { - return NumericAttributeFilterType._TYPE; - } - static get ICON_URL(): string { - return NumericAttributeFilterType._ICON_URL; - } - static get NAME(): string { - return NumericAttributeFilterType._NAME; - } - - private name: string; - private includeNoData: boolean; - private rangeMin: number; - private rangeMax: number; - - constructor(config: NumericAttributeFilterTypeConfig) { - super(); - this.name = config.attributeName; - this.includeNoData = !!config.includeNoData; // defaults to false on undefined - this.rangeMin = config.rangeMin; - this.rangeMax = config.rangeMax; - } - - static fromDict(dict: NumericAttributeFilterTypeDict): NumericAttributeFilterType { - return new NumericAttributeFilterType(dict); - } - - getMappingName(): string { - return NumericAttributeFilterType.TYPE; - } - - getIconUrl(): string { - return NumericAttributeFilterType.ICON_URL; - } - - toString(): string { - return NumericAttributeFilterType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - const parameters: Array<[string, string]> = [['includeNoData', this.includeNoData.toString()]]; - if (this.rangeMin) { - parameters.push(['rangeMin', this.rangeMin.toString()]); - } - if (this.rangeMax) { - parameters.push(['rangeMax', this.rangeMax.toString()]); - } - return parameters; - } - - toMappingDict(): NumericAttributeFilterTypeMappingDict { - return { - name: this.name, - includeNoData: this.includeNoData, - rangeMin: this.rangeMin, - rangeMax: this.rangeMax, - }; - } - - toDict(): NumericAttributeFilterTypeDict { - return { - operatorType: NumericAttributeFilterType.TYPE, - attributeName: this.name, - includeNoData: this.includeNoData, - rangeMin: this.rangeMin, - rangeMax: this.rangeMax, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return NumericAttributeFilterType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/ogr-raw-source-type.model.ts b/projects/wave-core/src/lib/operators/types/ogr-raw-source-type.model.ts deleted file mode 100644 index b1f8109d..00000000 --- a/projects/wave-core/src/lib/operators/types/ogr-raw-source-type.model.ts +++ /dev/null @@ -1,155 +0,0 @@ -import {OperatorType, OperatorTypeCloneOptions, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface OgrRawSourceTypeConfig { - filename: string; - layer_name?: string; - query_string?: string; - time: 'none' | 'start' | 'start+end' | 'start+duration'; - duration?: number | 'inf'; - time1_format?: MappingTimeFormat; - time2_format?: MappingTimeFormat; - columns: { - x?: string; - y?: string; - time1?: string; - time2?: string; - numeric: Array; - textual: Array; - }; - default?: string; // WKT definition of default value - force_ogr_time_filter?: boolean; - on_error: 'skip' | 'abort' | 'keep'; - provenance?: { - citation: string; - license: string; - uri: string; - }; -} - -// TODO: generalize and export -interface MappingTimeFormat { - format: 'custom' | 'seconds' | 'dmyhm' | 'iso'; - custom_format?: string; -} - -interface OgrRawSourceTypeMappingDict extends OperatorTypeMappingDict { - filename: string; - layer_name?: string; - time: 'none' | 'start' | 'start+end' | 'start+duration'; - duration?: number | 'inf'; - time1_format?: MappingTimeFormat; - time2_format?: MappingTimeFormat; - columns: { - x?: string; - y?: string; - time1?: string; - time2?: string; - numeric: Array; - textual: Array; - }; - default?: string; // WKT definition of default value - force_ogr_time_filter?: boolean; - on_error: 'skip' | 'abort' | 'keep'; - provenance?: { - citation: string; - license: string; - uri: string; - }; -} - -export interface OgrRawSourceTypeDict extends OperatorTypeDict { - filename: string; - layer_name?: string; - query_string?: string; - time: 'none' | 'start' | 'start+end' | 'start+duration'; - duration?: number | 'inf'; - time1_format?: MappingTimeFormat; - time2_format?: MappingTimeFormat; - columns: { - x?: string; - y?: string; - time1?: string; - time2?: string; - numeric: Array; - textual: Array; - }; - default?: string; // WKT definition of default value - force_ogr_time_filter?: boolean; - on_error: 'skip' | 'abort' | 'keep'; - provenance?: { - citation: string; - license: string; - uri: string; - }; -} - -/** - * The raster source type. - */ -export class OgrRawSourceType extends OperatorType { - private static _TYPE = 'ogr_raw_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(OgrRawSourceType._TYPE); - private static _NAME = 'GDAL OGR Raw Source'; - - static get TYPE(): string { - return OgrRawSourceType._TYPE; - } - - static get ICON_URL(): string { - return OgrRawSourceType._ICON_URL; - } - - static get NAME(): string { - return OgrRawSourceType._NAME; - } - - config: OgrRawSourceTypeConfig; - - static fromDict(dict: OgrRawSourceTypeDict): OgrRawSourceType { - return new OgrRawSourceType(dict); - } - - constructor(config: OgrRawSourceTypeConfig) { - super(); - this.config = config; - } - - getMappingName(): string { - return OgrRawSourceType.TYPE; - } - - getIconUrl(): string { - return OgrRawSourceType.ICON_URL; - } - - toString(): string { - return OgrRawSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['filename', this.config.query_string ? '' : this.config.filename.toString()], // FIXME: workaround for CronicalDB - ['layer_name', this.config.layer_name ? this.config.layer_name.toString() : ''], - ['query_string', this.config.query_string ? this.config.query_string.toString() : ''], - ['columns.time1', this.config.columns.time1 ? this.config.columns.time1.toString() : ''], - ['columns.time2', this.config.columns.time2 ? this.config.columns.time2.toString() : ''], - ['columns.numeric', this.config.columns.numeric.toString()], - ['columns.textual', this.config.columns.textual.toString()], - ]; - } - - toMappingDict(): OgrRawSourceTypeMappingDict { - return this.config; - } - - toDict(): OgrRawSourceTypeDict { - return { - operatorType: OgrRawSourceType.TYPE, - ...this.config, - }; - } - - cloneWithModifications(options?: OperatorTypeCloneOptions): OperatorType { - return new OgrRawSourceType(this.config); - } -} diff --git a/projects/wave-core/src/lib/operators/types/ogr-source-type.model.ts b/projects/wave-core/src/lib/operators/types/ogr-source-type.model.ts deleted file mode 100644 index 07056f12..00000000 --- a/projects/wave-core/src/lib/operators/types/ogr-source-type.model.ts +++ /dev/null @@ -1,102 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface OgrSourceTypeConfig { - dataset_id: string; - layer_id: string | number; - numeric: string[]; - textual: string[]; -} - -interface OgrSourceTypeMappingDict extends OperatorTypeMappingDict { - name: string; - layer_name: string | number; - numeric: string[]; - textual: string[]; -} - -export interface OgrSourceTypeDict extends OperatorTypeDict { - dataset_id: string; - layer_id: string | number; - numeric: string[]; - textual: string[]; -} - -/** - * The raster source type. - */ -export class OgrSourceType extends OperatorType { - private static _TYPE = 'ogr_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(OgrSourceType._TYPE); - private static _NAME = 'GDAL OGR Source'; - - static get TYPE(): string { - return OgrSourceType._TYPE; - } - static get ICON_URL(): string { - return OgrSourceType._ICON_URL; - } - static get NAME(): string { - return OgrSourceType._NAME; - } - - dataset_id: string; - layer_id: string | number; - numeric: string[]; - textual: string[]; - - static fromDict(dict: OgrSourceTypeDict): OgrSourceType { - return new OgrSourceType(dict); - } - - constructor(config: OgrSourceTypeConfig) { - super(); - this.dataset_id = config.dataset_id; - this.layer_id = config.layer_id; - this.numeric = config.numeric; - this.textual = config.textual; - } - - getMappingName(): string { - return OgrSourceType.TYPE; - } - - getIconUrl(): string { - return OgrSourceType.ICON_URL; - } - - toString(): string { - return OgrSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['dataset_id', this.dataset_id.toString()], - ['layer_id', this.layer_id.toString()], - ['numeric', this.numeric.toString()], - ['textual', this.textual.toString()], - ]; - } - - toMappingDict(): OgrSourceTypeMappingDict { - return { - name: this.dataset_id, - layer_name: this.layer_id, - numeric: this.numeric, - textual: this.textual, - }; - } - - toDict(): OgrSourceTypeDict { - return { - operatorType: OgrSourceType.TYPE, - dataset_id: this.dataset_id, - layer_id: this.layer_id, - numeric: this.numeric, - textual: this.textual, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return OgrSourceType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/piechart-type.model.ts b/projects/wave-core/src/lib/operators/types/piechart-type.model.ts deleted file mode 100644 index d9c9d52c..00000000 --- a/projects/wave-core/src/lib/operators/types/piechart-type.model.ts +++ /dev/null @@ -1,117 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -import {ResultType, ResultTypes} from '../result-type.model'; - -interface PieChartTypeMappingDict extends OperatorTypeMappingDict { - source: string; - result: string; -} - -export interface PieChartTypeDict extends OperatorTypeDict { - attribute: string; - inputType: string; -} - -interface PieChartTypeConfig { - attribute: string; - inputType: ResultType; -} - -/** - * The R type. - */ -export class PieChartType extends OperatorType { - private static _TYPE = 'piechart'; - private static _ICON_URL = OperatorType.createIconDataUrl(PieChartType._TYPE); - private static _NAME = 'Pie Chart'; - - static get TYPE(): string { - return PieChartType._TYPE; - } - static get ICON_URL(): string { - return PieChartType._ICON_URL; - } - static get NAME(): string { - return PieChartType._NAME; - } - - private code: string; - private attribute: string; - private inputType: ResultType; - private resultType: ResultType; - - static fromDict(dict: PieChartTypeDict): PieChartType { - return new PieChartType({ - attribute: dict.attribute, - inputType: ResultTypes.fromCode(dict.inputType), - }); - } - - constructor(config: PieChartTypeConfig) { - super(); - this.attribute = config.attribute; - this.inputType = config.inputType; - this.resultType = ResultTypes.PLOT; - - const camelInputType = this.inputType.toString().charAt(0).toUpperCase() + this.inputType.toString().substr(1).toLowerCase(); - - this.code = ` - features <- mapping.load${camelInputType}(0, mapping.qrect); - - if (length(features) > 0) { - - kv <- table(features$\`${config.attribute}\`); - - labels <- paste("(",names(kv),")", "\n", kv, sep=""); - - pie(kv, labels = labels); - - } else { - - plot.new(); - - mtext("Empty Dataset"); - - } - - `; - } - - getMappingName(): string { - return 'r_script'; - } - - getIconUrl(): string { - return PieChartType.ICON_URL; - } - - toString(): string { - return PieChartType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['code', this.code.toString()], - ['resultType', this.resultType.toString()], - ]; - } - - toMappingDict(): PieChartTypeMappingDict { - return { - source: this.code, - result: this.resultType.getCode(), - }; - } - - toDict(): PieChartTypeDict { - return { - operatorType: PieChartType.TYPE, - attribute: this.attribute, - inputType: this.inputType.getCode(), - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return PieChartType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/point-in-polygon-filter-type.model.ts b/projects/wave-core/src/lib/operators/types/point-in-polygon-filter-type.model.ts deleted file mode 100644 index fafcb71b..00000000 --- a/projects/wave-core/src/lib/operators/types/point-in-polygon-filter-type.model.ts +++ /dev/null @@ -1,64 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface PointInPolygonFilterTypeMappingDict extends OperatorTypeMappingDict {} - -export interface PointInPolygonFilterTypeDict extends OperatorTypeDict {} - -interface PointInPolygonFilterTypeConfig {} - -/** - * The Point in Polygon Filter type. - */ -export class PointInPolygonFilterType extends OperatorType { - private static _TYPE = 'point_in_polygon_filter'; - private static _ICON_URL = OperatorType.createIconDataUrl(PointInPolygonFilterType._TYPE); - private static _NAME = 'Point in Polygon Filter'; - - static get TYPE(): string { - return PointInPolygonFilterType._TYPE; - } - static get ICON_URL(): string { - return PointInPolygonFilterType._ICON_URL; - } - static get NAME(): string { - return PointInPolygonFilterType._NAME; - } - - constructor(config: PointInPolygonFilterTypeConfig) { - super(); - } - - static fromDict(dict: PointInPolygonFilterTypeDict): PointInPolygonFilterType { - return new PointInPolygonFilterType({}); - } - - getMappingName(): string { - return PointInPolygonFilterType.TYPE; - } - - getIconUrl(): string { - return PointInPolygonFilterType.ICON_URL; - } - - toString(): string { - return PointInPolygonFilterType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return []; - } - - toMappingDict(): PointInPolygonFilterTypeMappingDict { - return {}; - } - - toDict(): PointInPolygonFilterTypeDict { - return { - operatorType: PointInPolygonFilterType.TYPE, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return PointInPolygonFilterType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/projection-type.model.ts b/projects/wave-core/src/lib/operators/types/projection-type.model.ts deleted file mode 100644 index 263c7abc..00000000 --- a/projects/wave-core/src/lib/operators/types/projection-type.model.ts +++ /dev/null @@ -1,91 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -import {Projection, Projections} from '../projection.model'; - -interface ProjectionTypeConfig { - srcProjection: Projection; - destProjection: Projection; -} - -interface ProjectionTypeMappingDict extends OperatorTypeMappingDict { - src_projection: string; - dest_projection: string; -} - -export interface ProjectionTypeDict extends OperatorTypeDict { - srcProjection: string; - destProjection: string; -} - -/** - * The projection type. - */ -export class ProjectionType extends OperatorType { - private static _TYPE = 'projection'; - private static _ICON_URL = OperatorType.createIconDataUrl(ProjectionType._TYPE); - private static _NAME = 'Projection'; - - static get TYPE(): string { - return ProjectionType._TYPE; - } - static get ICON_URL(): string { - return ProjectionType._ICON_URL; - } - static get NAME(): string { - return ProjectionType._NAME; - } - - private srcProjection: Projection; - private destProjection: Projection; - - constructor(config: ProjectionTypeConfig) { - super(); - this.srcProjection = config.srcProjection; - this.destProjection = config.destProjection; - } - - static fromDict(dict: ProjectionTypeDict): ProjectionType { - return new ProjectionType({ - srcProjection: Projections.fromCode(dict.srcProjection), - destProjection: Projections.fromCode(dict.destProjection), - }); - } - - getMappingName(): string { - return ProjectionType.TYPE; - } - - getIconUrl(): string { - return ProjectionType.ICON_URL; - } - - toString(): string { - return ProjectionType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['srcProjection', this.srcProjection.toString()], - ['destProjection', this.destProjection.toString()], - ]; - } - - toMappingDict(): ProjectionTypeMappingDict { - return { - src_projection: this.srcProjection.getCode(), - dest_projection: this.destProjection.getCode(), - }; - } - - toDict(): ProjectionTypeDict { - return { - operatorType: ProjectionType.TYPE, - srcProjection: this.srcProjection.getCode(), - destProjection: this.destProjection.getCode(), - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return ProjectionType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/r-script-type.model.ts b/projects/wave-core/src/lib/operators/types/r-script-type.model.ts deleted file mode 100644 index a099a88b..00000000 --- a/projects/wave-core/src/lib/operators/types/r-script-type.model.ts +++ /dev/null @@ -1,91 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -import {ResultType, ResultTypes} from '../result-type.model'; - -interface RScriptTypeMappingDict extends OperatorTypeMappingDict { - source: string; - result: string; -} - -export interface RScriptTypeDict extends OperatorTypeDict { - code: string; - resultType: string; -} - -interface RScriptTypeConfig { - code: string; - resultType: ResultType; -} - -/** - * The R type. - */ -export class RScriptType extends OperatorType { - private static _TYPE = 'r_script'; - private static _ICON_URL = OperatorType.createIconDataUrl(RScriptType._TYPE); - private static _NAME = 'R Script'; - - static get TYPE(): string { - return RScriptType._TYPE; - } - static get ICON_URL(): string { - return RScriptType._ICON_URL; - } - static get NAME(): string { - return RScriptType._NAME; - } - - private code: string; - private resultType: ResultType; - - static fromDict(dict: RScriptTypeDict): RScriptType { - return new RScriptType({ - code: dict.code, - resultType: ResultTypes.fromCode(dict.resultType), - }); - } - - constructor(config: RScriptTypeConfig) { - super(); - this.code = config.code; - this.resultType = config.resultType; - } - - getMappingName(): string { - return RScriptType.TYPE; - } - - getIconUrl(): string { - return RScriptType.ICON_URL; - } - - toString(): string { - return RScriptType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['code', this.code.toString()], - ['resultType', this.resultType.toString()], - ]; - } - - toMappingDict(): RScriptTypeMappingDict { - return { - source: this.code, - result: this.resultType.getCode(), - }; - } - - toDict(): RScriptTypeDict { - return { - operatorType: RScriptType.TYPE, - code: this.code, - resultType: this.resultType.getCode(), - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return RScriptType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/raster-source-type.model.ts b/projects/wave-core/src/lib/operators/types/raster-source-type.model.ts deleted file mode 100644 index 72d953cf..00000000 --- a/projects/wave-core/src/lib/operators/types/raster-source-type.model.ts +++ /dev/null @@ -1,94 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface RasterSourceTypeConfig { - channel: number; - sourcename: string; - transform: boolean; -} - -interface RasterSourceTypeMappingDict extends OperatorTypeMappingDict { - channel: number; - sourcename: string; - transform: boolean; -} - -export interface RasterSourceTypeDict extends OperatorTypeDict { - channel: number; - sourcename: string; - transform: boolean; -} - -/** - * The raster source type. - */ -export class RasterSourceType extends OperatorType { - private static _TYPE = 'rasterdb_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(RasterSourceType._TYPE); - private static _NAME = 'Raster Source'; - - static get TYPE(): string { - return RasterSourceType._TYPE; - } - static get ICON_URL(): string { - return RasterSourceType._ICON_URL; - } - static get NAME(): string { - return RasterSourceType._NAME; - } - - private channel: number; - private sourcename: string; - private transform: boolean; - - constructor(config: RasterSourceTypeConfig) { - super(); - this.channel = config.channel; - this.sourcename = config.sourcename; - this.transform = config.transform; - } - - static fromDict(dict: RasterSourceTypeDict): RasterSourceType { - return new RasterSourceType(dict); - } - - getMappingName(): string { - return RasterSourceType.TYPE; - } - - getIconUrl(): string { - return RasterSourceType.ICON_URL; - } - - toString(): string { - return RasterSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['channel', this.channel.toString()], - ['sourcename', this.sourcename.toString()], - ['transform', this.transform.toString()], - ]; - } - - toMappingDict(): RasterSourceTypeMappingDict { - return { - sourcename: this.sourcename, - channel: this.channel, - transform: this.transform, - }; - } - - toDict(): RasterSourceTypeDict { - return { - operatorType: RasterSourceType.TYPE, - sourcename: this.sourcename, - channel: this.channel, - transform: this.transform, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return RasterSourceType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/raster-value-extraction-type.model.ts b/projects/wave-core/src/lib/operators/types/raster-value-extraction-type.model.ts deleted file mode 100644 index 45f86ea3..00000000 --- a/projects/wave-core/src/lib/operators/types/raster-value-extraction-type.model.ts +++ /dev/null @@ -1,94 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface RasterValueExtractionTypeMappingDict extends OperatorTypeMappingDict { - xResolution: number; - yResolution: number; - names: Array; -} - -export interface RasterValueExtractionTypeDict extends OperatorTypeDict { - xResolution: number; - yResolution: number; - attributeNames: Array; -} - -interface RasterValueExtractionTypeConfig { - xResolution: number; - yResolution: number; - attributeNames: Array; -} - -/** - * The raster value extraction type. - */ -export class RasterValueExtractionType extends OperatorType { - private static _TYPE = 'raster_value_extraction'; - private static _ICON_URL = OperatorType.createIconDataUrl(RasterValueExtractionType._TYPE); - private static _NAME = 'Raster Value Extraction'; - - static get TYPE(): string { - return RasterValueExtractionType._TYPE; - } - static get ICON_URL(): string { - return RasterValueExtractionType._ICON_URL; - } - static get NAME(): string { - return RasterValueExtractionType._NAME; - } - - private xResolution: number; - private yResolution: number; - private attributeNames: Array; - - constructor(config: RasterValueExtractionTypeConfig) { - super(); - this.xResolution = config.xResolution; - this.yResolution = config.yResolution; - this.attributeNames = config.attributeNames; - } - - static fromDict(dict: RasterValueExtractionTypeDict): RasterValueExtractionType { - return new RasterValueExtractionType(dict); - } - - getMappingName(): string { - return RasterValueExtractionType.TYPE; - } - - getIconUrl(): string { - return RasterValueExtractionType.ICON_URL; - } - - toString(): string { - return RasterValueExtractionType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['xResolution', this.xResolution.toString()], - ['yResolution', this.yResolution.toString()], - ['attributeNames', this.attributeNames.join(', ')], - ]; - } - - toMappingDict(): RasterValueExtractionTypeMappingDict { - return { - xResolution: this.xResolution, - yResolution: this.yResolution, - names: this.attributeNames, - }; - } - - toDict(): RasterValueExtractionTypeDict { - return { - operatorType: RasterValueExtractionType.TYPE, - xResolution: this.xResolution, - yResolution: this.yResolution, - attributeNames: this.attributeNames, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return RasterValueExtractionType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/rasterize-polygon-type.model.ts b/projects/wave-core/src/lib/operators/types/rasterize-polygon-type.model.ts deleted file mode 100644 index 9b2f8e3c..00000000 --- a/projects/wave-core/src/lib/operators/types/rasterize-polygon-type.model.ts +++ /dev/null @@ -1,64 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface RasterizePolygonTypeMappingDict extends OperatorTypeMappingDict {} // eslint-disable-line @typescript-eslint/no-empty-interface - -export interface RasterizePolygonTypeDict extends OperatorTypeDict {} // eslint-disable-line @typescript-eslint/no-empty-interface - -interface RasterizePolygonTypeConfig {} // eslint-disable-line @typescript-eslint/no-empty-interface - -/** - * The raster value extraction type. - */ -export class RasterizePolygonType extends OperatorType { - private static _TYPE = 'rasterize_polygon'; - private static _ICON_URL = OperatorType.createIconDataUrl(RasterizePolygonType._TYPE); - private static _NAME = 'Rasterize Polygon'; - - static get TYPE(): string { - return RasterizePolygonType._TYPE; - } - static get ICON_URL(): string { - return RasterizePolygonType._ICON_URL; - } - static get NAME(): string { - return RasterizePolygonType._NAME; - } - - static fromDict(dict: RasterizePolygonTypeDict): RasterizePolygonType { - return new RasterizePolygonType(dict); - } - - constructor(config: RasterizePolygonTypeConfig) { - super(); - } - - getMappingName(): string { - return RasterizePolygonType.TYPE; - } - - getIconUrl(): string { - return RasterizePolygonType.ICON_URL; - } - - toString(): string { - return RasterizePolygonType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return []; - } - - toMappingDict(): RasterizePolygonTypeMappingDict { - return {}; - } - - toDict(): RasterizePolygonTypeDict { - return { - operatorType: RasterizePolygonType.TYPE, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return RasterizePolygonType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/rgba-composite-type.model.ts b/projects/wave-core/src/lib/operators/types/rgba-composite-type.model.ts deleted file mode 100644 index 249d92e8..00000000 --- a/projects/wave-core/src/lib/operators/types/rgba-composite-type.model.ts +++ /dev/null @@ -1,159 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -/** - * Each red, green and blue layer needs a minimum and maximum values - * to scale the color intensity in between. A scale between 0 and 1 - * allows for further emphasis on colors. - */ -interface RgbaCompositeTypeConfig { - rasterRedMin: number; - rasterRedMax: number; - rasterRedScale: number; - rasterGreenMin: number; - rasterGreenMax: number; - rasterGreenScale: number; - rasterBlueMin: number; - rasterBlueMax: number; - rasterBlueScale: number; -} - -interface RgbaCompositeTypeMappingDict extends OperatorTypeMappingDict { - raster_r_min: number; - raster_r_max: number; - raster_r_scale: number; - raster_g_min: number; - raster_g_max: number; - raster_g_scale: number; - raster_b_min: number; - raster_b_max: number; - raster_b_scale: number; -} - -export interface RgbaCompositeTypeDict extends OperatorTypeDict { - rasterRedMin: number; - rasterRedMax: number; - rasterRedScale: number; - rasterGreenMin: number; - rasterGreenMax: number; - rasterGreenScale: number; - rasterBlueMin: number; - rasterBlueMax: number; - rasterBlueScale: number; -} - -/** - * The RGBA composite type. - */ -export class RgbaCompositeType extends OperatorType { - private static _TYPE = 'rgba_composite'; - private static _ICON_URL = OperatorType.createIconDataUrl(RgbaCompositeType._TYPE); - private static _NAME = 'RGBA Composite'; - - static get TYPE(): string { - return RgbaCompositeType._TYPE; - } - - static get ICON_URL(): string { - return RgbaCompositeType._ICON_URL; - } - - static get NAME(): string { - return RgbaCompositeType._NAME; - } - - readonly rasterRedMin: number; - readonly rasterRedMax: number; - readonly rasterRedScale: number; - readonly rasterGreenMin: number; - readonly rasterGreenMax: number; - readonly rasterGreenScale: number; - readonly rasterBlueMin: number; - readonly rasterBlueMax: number; - readonly rasterBlueScale: number; - - constructor(config: RgbaCompositeTypeConfig) { - super(); - this.rasterRedMin = config.rasterRedMin; - this.rasterRedMax = config.rasterRedMax; - this.rasterRedScale = config.rasterRedScale; - this.rasterGreenMin = config.rasterGreenMin; - this.rasterGreenMax = config.rasterGreenMax; - this.rasterGreenScale = config.rasterGreenScale; - this.rasterBlueMin = config.rasterBlueMin; - this.rasterBlueMax = config.rasterBlueMax; - this.rasterBlueScale = config.rasterBlueScale; - } - - static fromDict(dict: RgbaCompositeTypeDict): RgbaCompositeType { - return new RgbaCompositeType({ - rasterRedMin: dict.rasterRedMin, - rasterRedMax: dict.rasterRedMax, - rasterRedScale: dict.rasterRedScale, - rasterGreenMin: dict.rasterGreenMin, - rasterGreenMax: dict.rasterGreenMax, - rasterGreenScale: dict.rasterGreenScale, - rasterBlueMin: dict.rasterBlueMin, - rasterBlueMax: dict.rasterBlueMax, - rasterBlueScale: dict.rasterBlueScale, - }); - } - - getMappingName(): string { - return RgbaCompositeType.TYPE; - } - - getIconUrl(): string { - return RgbaCompositeType.ICON_URL; - } - - toString(): string { - return RgbaCompositeType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['rasterRedMin', this.rasterRedMin.toString()], - ['rasterRedMax', this.rasterRedMax.toString()], - ['rasterRedScale', this.rasterRedScale.toString()], - ['rasterGreenMin', this.rasterGreenMin.toString()], - ['rasterGreenMax', this.rasterGreenMax.toString()], - ['rasterGreenScale', this.rasterGreenScale.toString()], - ['rasterBlueMin', this.rasterBlueMin.toString()], - ['rasterBlueMax', this.rasterBlueMax.toString()], - ['rasterBlueScale', this.rasterBlueScale.toString()], - ]; - } - - toMappingDict(): RgbaCompositeTypeMappingDict { - return { - raster_r_min: this.rasterRedMin, - raster_r_max: this.rasterRedMax, - raster_r_scale: this.rasterRedScale, - raster_g_min: this.rasterGreenMin, - raster_g_max: this.rasterGreenMax, - raster_g_scale: this.rasterGreenScale, - raster_b_min: this.rasterBlueMin, - raster_b_max: this.rasterBlueMax, - raster_b_scale: this.rasterBlueScale, - }; - } - - toDict(): RgbaCompositeTypeDict { - return { - operatorType: RgbaCompositeType.TYPE, - rasterRedMin: this.rasterRedMin, - rasterRedMax: this.rasterRedMax, - rasterRedScale: this.rasterRedScale, - rasterGreenMin: this.rasterGreenMin, - rasterGreenMax: this.rasterGreenMax, - rasterGreenScale: this.rasterGreenScale, - rasterBlueMin: this.rasterBlueMin, - rasterBlueMax: this.rasterBlueMax, - rasterBlueScale: this.rasterBlueScale, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return RgbaCompositeType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/scatterplot-type.model.ts b/projects/wave-core/src/lib/operators/types/scatterplot-type.model.ts deleted file mode 100644 index d7a45138..00000000 --- a/projects/wave-core/src/lib/operators/types/scatterplot-type.model.ts +++ /dev/null @@ -1,138 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -import {ResultType, ResultTypes} from '../result-type.model'; - -interface ScatterPlotTypeMappingDict extends OperatorTypeMappingDict { - source: string; - result: string; -} - -export interface ScatterPlotTypeDict extends OperatorTypeDict { - attribute1: string; - attribute2: string; - regression: boolean; - inputType: string; -} - -interface ScatterPlotTypeConfig { - attribute1: string; - attribute2: string; - regression: boolean; - inputType: ResultType; -} - -export class ScatterPlotType extends OperatorType { - private static _TYPE = 'scatterplot'; - private static _ICON_URL = OperatorType.createIconDataUrl(ScatterPlotType._TYPE); - private static _NAME = 'Scatter Plot'; - - static get TYPE(): string { - return ScatterPlotType._TYPE; - } - static get ICON_URL(): string { - return ScatterPlotType._ICON_URL; - } - static get NAME(): string { - return ScatterPlotType._NAME; - } - - private code: string; - private attribute1: string; - private attribute2: string; - private regression: boolean; - private inputType: ResultType; - private resultType: ResultType; - - static fromDict(dict: ScatterPlotTypeDict): ScatterPlotType { - return new ScatterPlotType({ - attribute1: dict.attribute1, - attribute2: dict.attribute2, - regression: dict.regression, - inputType: ResultTypes.fromCode(dict.inputType), - }); - } - - constructor(config: ScatterPlotTypeConfig) { - super(); - - this.attribute1 = config.attribute1; - this.attribute2 = config.attribute2; - this.regression = config.regression; - this.inputType = config.inputType; - - const camelInputType = this.inputType.toString().charAt(0).toUpperCase() + this.inputType.toString().substr(1).toLowerCase(); - - this.code = ` - library(ggplot2); - - features <- mapping.load${camelInputType}(0, mapping.qrect); - - if (length(features) > 0) { - - first = features$\`${config.attribute1}\`; - - second = features$\`${config.attribute2}\`; - - df <- data.frame(xVal = first, yVal = second); - - p <- ( - ggplot(df, aes(x=xVal, y=yVal)) - + geom_point(shape=1) - ${this.regression ? '+ geom_smooth(method=lm, se=FALSE)' : ''} - + labs(x = "${config.attribute1}", y = "${config.attribute2}") - ); - - print(p); - - } else { - - plot.new(); - - mtext("Empty Dataset"); - - } - `; - - this.resultType = ResultTypes.PLOT; - } - - getMappingName(): string { - return 'r_script'; - } - - getIconUrl(): string { - return ScatterPlotType.ICON_URL; - } - - toString(): string { - return ScatterPlotType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['code', this.code.toString()], - ['resultType', this.resultType.toString()], - ]; - } - - toMappingDict(): ScatterPlotTypeMappingDict { - return { - source: this.code, - result: this.resultType.getCode(), - }; - } - - toDict(): ScatterPlotTypeDict { - return { - operatorType: ScatterPlotType.TYPE, - attribute1: this.attribute1, - attribute2: this.attribute2, - regression: this.regression, - inputType: this.inputType.getCode(), - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return ScatterPlotType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/statistics-type.model.ts b/projects/wave-core/src/lib/operators/types/statistics-type.model.ts deleted file mode 100644 index 58c40686..00000000 --- a/projects/wave-core/src/lib/operators/types/statistics-type.model.ts +++ /dev/null @@ -1,102 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface StatisticsTypeMappingDict extends OperatorTypeMappingDict { - raster_width?: number; - raster_height?: number; -} - -export interface StatisticsTypeDict extends OperatorTypeDict { - raster_width?: number; - raster_height?: number; -} - -/** - * If the statistic is for a raster value, it is necessary to specify - * query resolutions (in pixels) on which the statistics are calculated. - */ -interface StatisticsTypeConfig { - raster_width?: number; - raster_height?: number; -} - -/** - * The layer statistics type. - */ -export class StatisticsType extends OperatorType { - private static _TYPE = 'statistics'; - private static _ICON_URL = OperatorType.createIconDataUrl(StatisticsType._TYPE); - private static _NAME = 'Layer Statistics'; - - static get TYPE(): string { - return StatisticsType._TYPE; - } - - static get ICON_URL(): string { - return StatisticsType._ICON_URL; - } - - static get NAME(): string { - return StatisticsType._NAME; - } - - private raster_width: number; - private raster_height: number; - - constructor(config: StatisticsTypeConfig) { - super(); - this.raster_width = config.raster_width ? config.raster_width : undefined; - this.raster_height = config.raster_height ? config.raster_height : undefined; - } - - static fromDict(dict: StatisticsTypeDict): StatisticsType { - return new StatisticsType(dict); - } - - getMappingName(): string { - return StatisticsType.TYPE; - } - - getIconUrl(): string { - return StatisticsType.ICON_URL; - } - - toString(): string { - return StatisticsType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['raster_width', this.raster_width.toString()], - ['raster_height', this.raster_height.toString()], - ]; - } - - toMappingDict(): StatisticsTypeMappingDict { - if (this.raster_width || this.raster_height) { - return { - raster_height: this.raster_height, - raster_width: this.raster_width, - }; - } - - return {}; - } - - toDict(): StatisticsTypeDict { - if (this.raster_width || this.raster_height) { - return { - operatorType: StatisticsType.TYPE, - raster_height: this.raster_height, - raster_width: this.raster_width, - }; - } - - return { - operatorType: StatisticsType.TYPE, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return StatisticsType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/temporal-aggregation-type.ts b/projects/wave-core/src/lib/operators/types/temporal-aggregation-type.ts deleted file mode 100644 index 6ff364f3..00000000 --- a/projects/wave-core/src/lib/operators/types/temporal-aggregation-type.ts +++ /dev/null @@ -1,91 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -type AggregationType = 'min' | 'max' | 'avg'; - -interface TemporalAggregationTypeMappingDict extends OperatorTypeMappingDict { - duration: number; - aggregation: AggregationType; -} - -export interface TemporalAggregationTypeDict extends OperatorTypeDict { - duration: number; - aggregation: AggregationType; -} - -interface TemporalAggregationTypeConfig { - duration: number; - aggregation: AggregationType; -} - -/** - * The temporal aggregation type. - */ -export class TemporalAggregationType extends OperatorType { - private static _TYPE = 'temporal_aggregation'; - private static _ICON_URL = OperatorType.createIconDataUrl(TemporalAggregationType._TYPE); - private static _NAME = 'Temporal Aggregation'; - - static get TYPE(): string { - return TemporalAggregationType._TYPE; - } - static get ICON_URL(): string { - return TemporalAggregationType._ICON_URL; - } - static get NAME(): string { - return TemporalAggregationType._NAME; - } - - private duration: number; - private aggregation: AggregationType; - - static fromDict(dict: TemporalAggregationTypeDict): TemporalAggregationType { - return new TemporalAggregationType({ - duration: dict.duration, - aggregation: dict.aggregation, - }); - } - - constructor(config: TemporalAggregationTypeConfig) { - super(); - this.duration = config.duration; - this.aggregation = config.aggregation; - } - - getMappingName(): string { - return TemporalAggregationType.TYPE; - } - - getIconUrl(): string { - return TemporalAggregationType.ICON_URL; - } - - toString(): string { - return TemporalAggregationType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['duration', this.duration.toString()], - ['aggregation', this.aggregation.toString()], - ]; - } - - toMappingDict(): TemporalAggregationTypeMappingDict { - return { - duration: this.duration, - aggregation: this.aggregation, - }; - } - - toDict(): TemporalAggregationTypeDict { - return { - operatorType: TemporalAggregationType.TYPE, - duration: this.duration, - aggregation: this.aggregation, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return TemporalAggregationType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/textual-attribute-filter-type.model.ts b/projects/wave-core/src/lib/operators/types/textual-attribute-filter-type.model.ts deleted file mode 100644 index 4db781cc..00000000 --- a/projects/wave-core/src/lib/operators/types/textual-attribute-filter-type.model.ts +++ /dev/null @@ -1,119 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -interface TextualAttributeFilterTypeMappingDict extends OperatorTypeMappingDict { - name: string; - engine: string; - searchString: string; -} - -export interface TextualAttributeFilterTypeDict extends OperatorTypeDict { - attributeName: string; - engine: string; - searchString: string; -} - -export enum TextualAttributeFilterEngineType { - EXACT = 'exact', - CONTAINS = 'contains', - STARTSWITH = 'startswith', -} - -interface TextualAttributeFilterTypeConfig { - attributeName: string; - engine: TextualAttributeFilterEngineType; - searchString: string; -} - -/** - * The Textual attribute filter type. - */ -export class TextualAttributeFilterType extends OperatorType { - private static _TYPE = 'textual_attribute_filter'; - private static _ICON_URL = OperatorType.createIconDataUrl(TextualAttributeFilterType._TYPE); - private static _NAME = 'Textual Attribute Filter'; - - static get TYPE(): string { - return TextualAttributeFilterType._TYPE; - } - - static get ICON_URL(): string { - return TextualAttributeFilterType._ICON_URL; - } - - static get NAME(): string { - return TextualAttributeFilterType._NAME; - } - - private attributeName: string; - private engine: TextualAttributeFilterEngineType; - private searchString: string; - - static fromDict(dict: TextualAttributeFilterTypeDict): TextualAttributeFilterType { - let engine: TextualAttributeFilterEngineType; - switch (dict.engine) { - case 'exact': - engine = TextualAttributeFilterEngineType.EXACT; - break; - case 'contains': - engine = TextualAttributeFilterEngineType.CONTAINS; - break; - case 'startswith': - engine = TextualAttributeFilterEngineType.STARTSWITH; - break; - } - - return new TextualAttributeFilterType({ - attributeName: dict.attributeName, - engine: engine, - searchString: dict.searchString, - }); - } - - constructor(config: TextualAttributeFilterTypeConfig) { - super(); - this.attributeName = config.attributeName; - this.engine = config.engine; - this.searchString = config.searchString; - } - - getMappingName(): string { - return TextualAttributeFilterType.TYPE; - } - - getIconUrl(): string { - return TextualAttributeFilterType.ICON_URL; - } - - toString(): string { - return TextualAttributeFilterType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['attributeName', this.attributeName.toString()], - ['filter engine', this.engine.toString()], - ['searchString', this.searchString.toString()], - ]; - } - - toMappingDict(): TextualAttributeFilterTypeMappingDict { - return { - name: this.attributeName, - engine: this.engine, - searchString: this.searchString, - }; - } - - toDict(): TextualAttributeFilterTypeDict { - return { - operatorType: TextualAttributeFilterType.TYPE, - attributeName: this.attributeName, - engine: this.engine, - searchString: this.searchString, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return TextualAttributeFilterType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/timeplot-type.model.ts b/projects/wave-core/src/lib/operators/types/timeplot-type.model.ts deleted file mode 100644 index 52e8a0f4..00000000 --- a/projects/wave-core/src/lib/operators/types/timeplot-type.model.ts +++ /dev/null @@ -1,146 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -import {ResultType, ResultTypes} from '../result-type.model'; - -interface TimePlotTypeMappingDict extends OperatorTypeMappingDict { - source: string; - result: string; -} - -export interface TimePlotTypeDict extends OperatorTypeDict { - attribute: string; - isGrouping: boolean; - grouping: string; - time: string; - inputType: string; -} - -interface TimePlotTypeConfig { - attribute: string; - isGrouping: boolean; - grouping: string; - time: string; - inputType: ResultType; -} - -export class TimePlotType extends OperatorType { - private static _TYPE = 'timeplot'; - private static _ICON_URL = OperatorType.createIconDataUrl(TimePlotType._TYPE); - private static _NAME = 'Time Plot'; - - static get TYPE(): string { - return TimePlotType._TYPE; - } - static get ICON_URL(): string { - return TimePlotType._ICON_URL; - } - static get NAME(): string { - return TimePlotType._NAME; - } - - private code: string; - private attribute: string; - private isGrouping: boolean; - private grouping: string; - private time: string; - private inputType: ResultType; - private resultType: ResultType; - - static fromDict(dict: TimePlotTypeDict): TimePlotType { - return new TimePlotType({ - attribute: dict.attribute, - isGrouping: dict.isGrouping, - grouping: dict.grouping, - time: dict.time, - inputType: ResultTypes.fromCode(dict.inputType), - }); - } - - constructor(config: TimePlotTypeConfig) { - super(); - this.attribute = config.attribute; - this.isGrouping = config.isGrouping; - this.grouping = config.grouping; - this.time = config.time; - this.inputType = config.inputType; - this.resultType = ResultTypes.PLOT; - - const camelInputType = this.inputType.toString().charAt(0).toUpperCase() + this.inputType.toString().substr(1).toLowerCase(); - const grouping = this.isGrouping ? 'grouping = data$`' + config.grouping + '`;' : ''; - const df = this.isGrouping ? 'data.frame(start, attribute, grouping);' : 'data.frame(start, attribute);'; - const ggplot = this.isGrouping - ? 'ggplot(df, aes(x=start, y=attribute, group=grouping, color=grouping))' - : 'ggplot(df, aes(x=start,y=attribute))'; - this.code = ` -library(ggplot2); - -data <- tryCatch(mapping.load${camelInputType}(0, mapping.qrect), error = function(e) NA) -if (is.na(data)) { -plot.new(); -mtext("Dataset has no data in the specified time chunk"); -} else { -if (all(names(data) != 'time_start')) { -plot.new(); -mtext("Dataset has no temporal information"); -} else { -attr = attributes(data@data)$names[1]; -query_start = mapping.qrect$t1; -query_end = mapping.qrect$t2; -query_lim_posix = c(as.POSIXct(query_start, origin="1970-01-01", tz = "GMT"), as.POSIXct(query_end, origin="1970-01-01", tz = "GMT")); -start = as.POSIXct(data$time_start, origin="1970-01-01", tz="GMT"); -attribute = data$\`${this.attribute}\`; -${grouping} -df = ${df} -p = ( - ${ggplot} - + geom_line() - + geom_point() - + scale_x_datetime(limits=query_lim_posix) - + xlab("Time") + ylab(\"${this.attribute}\") -) -print(p) -} -}`; - } - - getMappingName(): string { - return 'r_script'; - } - - getIconUrl(): string { - return TimePlotType.ICON_URL; - } - - toString(): string { - return TimePlotType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['code', this.code.toString()], - ['resultType', this.resultType.toString()], - ]; - } - - toMappingDict(): TimePlotTypeMappingDict { - return { - source: this.code, - result: this.resultType.getCode(), - }; - } - - toDict(): TimePlotTypeDict { - return { - operatorType: TimePlotType.TYPE, - attribute: this.attribute, - isGrouping: this.isGrouping, - grouping: this.grouping, - time: this.time, - inputType: this.inputType.getCode(), - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return TimePlotType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/types/type-factory.service.ts b/projects/wave-core/src/lib/operators/types/type-factory.service.ts deleted file mode 100644 index 87eadf30..00000000 --- a/projects/wave-core/src/lib/operators/types/type-factory.service.ts +++ /dev/null @@ -1,119 +0,0 @@ -import {OperatorType, OperatorTypeDict} from '../operator-type.model'; - -import {NumericAttributeFilterType, NumericAttributeFilterTypeDict} from './numeric-attribute-filter-type.model'; -import {RasterValueExtractionType, RasterValueExtractionTypeDict} from './raster-value-extraction-type.model'; -import {ExpressionType, ExpressionTypeDict} from './expression-type.model'; -import {ProjectionType, ProjectionTypeDict} from './projection-type.model'; -import {GFBioSourceType, GFBioSourceTypeDict} from './gfbio-source-type.model'; -import {RasterSourceType, RasterSourceTypeDict} from './raster-source-type.model'; -import {HistogramType, HistogramTypeDict} from './histogram-type.model'; -import {RScriptType, RScriptTypeDict} from './r-script-type.model'; -import {PointInPolygonFilterType, PointInPolygonFilterTypeDict} from './point-in-polygon-filter-type.model'; -import {WKTSourceType, WKTSourceTypeDict} from './wkt-source-type.model'; -import { - MsgCo2CorrectionType, - MsgPansharpenType, - MsgPansharpenTypeDict, - MsgRadianceType, - MsgReflectanceType, - MsgReflectanceTypeDict, - MsgSofosGccThermalThresholdType, - MsgSolarangleType, - MsgSolarangleTypeDict, - MsgTemperatureType, -} from './msg-types.model'; -import {CsvSourceType, CsvSourceTypeDict} from './csv-source-type.model'; -import {ClassificationType, ClassificationTypeDict} from './classification-type.model'; -import {FeatureCollectionDBSourceType, FeatureCollectionDBSourceTypeDict} from './feature-collection-db-source-type.model'; -import {TextualAttributeFilterType, TextualAttributeFilterTypeDict} from './textual-attribute-filter-type.model'; -import {GdalSourceType, GdalSourceTypeDict} from './gdal-source-type.model'; -import {ScatterPlotType, ScatterPlotTypeDict} from './scatterplot-type.model'; -import {BoxPlotType, BoxPlotTypeDict} from './boxplot-type.model'; -import {PieChartType, PieChartTypeDict} from './piechart-type.model'; -import {RasterizePolygonType, RasterizePolygonTypeDict} from './rasterize-polygon-type.model'; -import {HeatmapType, HeatmapTypeDict} from './heatmap-type.model'; -import {OgrSourceType, OgrSourceTypeDict} from './ogr-source-type.model'; -import {OgrRawSourceType, OgrRawSourceTypeDict} from './ogr-raw-source-type.model'; -import {ChronicleDBSourceType, ChronicleDBSourceTypeDict} from './chronicle-db-source-type.model'; -import {TimePlotType, TimePlotTypeDict} from './timeplot-type.model'; -import {StatisticsType, StatisticsTypeDict} from './statistics-type.model'; -import {RgbaCompositeType, RgbaCompositeTypeDict} from './rgba-composite-type.model'; - -type Type = string; -type Deserializer = (dict: OperatorTypeDict) => OperatorType; - -/** - * A simple factory for de-serializing operator types. - */ -export class OperatorTypeFactory { - protected static readonly typeDeserializers: Map = OperatorTypeFactory.defaultDeserializers(); - - protected static defaultDeserializers(): Map { - const typeDeserializers = new Map(); - - typeDeserializers.set(NumericAttributeFilterType.TYPE, (dict) => - NumericAttributeFilterType.fromDict(dict as NumericAttributeFilterTypeDict), - ); - typeDeserializers.set(TextualAttributeFilterType.TYPE, (dict) => - TextualAttributeFilterType.fromDict(dict as TextualAttributeFilterTypeDict), - ); - typeDeserializers.set(RasterValueExtractionType.TYPE, (dict) => - RasterValueExtractionType.fromDict(dict as RasterValueExtractionTypeDict), - ); - typeDeserializers.set(ExpressionType.TYPE, (dict) => ExpressionType.fromDict(dict as ExpressionTypeDict)); - typeDeserializers.set(ProjectionType.TYPE, (dict) => ProjectionType.fromDict(dict as ProjectionTypeDict)); - typeDeserializers.set(GFBioSourceType.TYPE, (dict) => GFBioSourceType.fromDict(dict as GFBioSourceTypeDict)); - typeDeserializers.set(RasterSourceType.TYPE, (dict) => RasterSourceType.fromDict(dict as RasterSourceTypeDict)); - typeDeserializers.set(GdalSourceType.TYPE, (dict) => GdalSourceType.fromDict(dict as GdalSourceTypeDict)); - typeDeserializers.set(OgrSourceType.TYPE, (dict) => OgrSourceType.fromDict(dict as OgrSourceTypeDict)); - typeDeserializers.set(HistogramType.TYPE, (dict) => HistogramType.fromDict(dict as HistogramTypeDict)); - typeDeserializers.set(RScriptType.TYPE, (dict) => RScriptType.fromDict(dict as RScriptTypeDict)); - typeDeserializers.set(PointInPolygonFilterType.TYPE, (dict) => - PointInPolygonFilterType.fromDict(dict as PointInPolygonFilterTypeDict), - ); - typeDeserializers.set(WKTSourceType.TYPE, (dict) => WKTSourceType.fromDict(dict as WKTSourceTypeDict)); - typeDeserializers.set(MsgRadianceType.TYPE, (dict) => MsgRadianceType.fromDict(dict)); - typeDeserializers.set(MsgReflectanceType.TYPE, (dict) => MsgReflectanceType.fromDict(dict as MsgReflectanceTypeDict)); - typeDeserializers.set(MsgSolarangleType.TYPE, (dict) => MsgSolarangleType.fromDict(dict as MsgSolarangleTypeDict)); - typeDeserializers.set(MsgTemperatureType.TYPE, (dict) => MsgTemperatureType.fromDict(dict)); - typeDeserializers.set(MsgPansharpenType.TYPE, (dict) => MsgPansharpenType.fromDict(dict as MsgPansharpenTypeDict)); - typeDeserializers.set(MsgCo2CorrectionType.TYPE, (dict) => MsgCo2CorrectionType.fromDict(dict)); - typeDeserializers.set(MsgSofosGccThermalThresholdType.TYPE, (dict) => MsgSofosGccThermalThresholdType.fromDict(dict)); - typeDeserializers.set(CsvSourceType.TYPE, (dict) => CsvSourceType.fromDict(dict as CsvSourceTypeDict)); - typeDeserializers.set(ClassificationType.TYPE, (dict) => ClassificationType.fromDict(dict as ClassificationTypeDict)); - typeDeserializers.set(FeatureCollectionDBSourceType.TYPE, (dict) => - FeatureCollectionDBSourceType.fromDict(dict as FeatureCollectionDBSourceTypeDict), - ); - typeDeserializers.set(ScatterPlotType.TYPE, (dict) => ScatterPlotType.fromDict(dict as ScatterPlotTypeDict)); - typeDeserializers.set(BoxPlotType.TYPE, (dict) => BoxPlotType.fromDict(dict as BoxPlotTypeDict)); - typeDeserializers.set(PieChartType.TYPE, (dict) => PieChartType.fromDict(dict as PieChartTypeDict)); - typeDeserializers.set(RasterizePolygonType.TYPE, (dict) => RasterizePolygonType.fromDict(dict as RasterizePolygonTypeDict)); - typeDeserializers.set(HeatmapType.TYPE, (dict) => HeatmapType.fromDict(dict as HeatmapTypeDict)); - typeDeserializers.set(StatisticsType.TYPE, (dict) => StatisticsType.fromDict(dict as StatisticsTypeDict)); - typeDeserializers.set(TimePlotType.TYPE, (dict) => TimePlotType.fromDict(dict as TimePlotTypeDict)); - typeDeserializers.set(RgbaCompositeType.TYPE, (dict) => RgbaCompositeType.fromDict(dict as RgbaCompositeTypeDict)); - typeDeserializers.set(ChronicleDBSourceType.TYPE, (dict) => ChronicleDBSourceType.fromDict(dict as ChronicleDBSourceTypeDict)); - typeDeserializers.set(OgrRawSourceType.TYPE, (dict) => OgrRawSourceType.fromDict(dict as OgrRawSourceTypeDict)); - - return typeDeserializers; - } - - /** - * Add a new type deserializer (fromDict) to the factory - */ - static addType(type: Type, fromDict: Deserializer) { - OperatorTypeFactory.typeDeserializers.set(type, fromDict); - } - - /** - * Create operator type from serialized data. - */ - static fromDict(dict: OperatorTypeDict): OperatorType { - const fromDict = OperatorTypeFactory.typeDeserializers.get(dict.operatorType); - if (fromDict) { - return fromDict(dict); - } else { - throw Error(`There is not factory method defined for operator »${dict.operatorType}«.`); - } - } -} diff --git a/projects/wave-core/src/lib/operators/types/wkt-source-type.model.ts b/projects/wave-core/src/lib/operators/types/wkt-source-type.model.ts deleted file mode 100644 index cbbf77b5..00000000 --- a/projects/wave-core/src/lib/operators/types/wkt-source-type.model.ts +++ /dev/null @@ -1,91 +0,0 @@ -import {OperatorType, OperatorTypeDict, OperatorTypeMappingDict} from '../operator-type.model'; - -import {ResultType, ResultTypes} from '../result-type.model'; - -interface WKTSourceTypeMappingDict extends OperatorTypeMappingDict { - type: string; - wkt: string; -} - -export interface WKTSourceTypeDict extends OperatorTypeDict { - type: string; - wkt: string; -} - -interface WKTSourceTypeConfig { - type: ResultType; - wkt: string; -} - -/** - * The WKT Source type. - */ -export class WKTSourceType extends OperatorType { - private static _TYPE = 'wkt_source'; - private static _ICON_URL = OperatorType.createIconDataUrl(WKTSourceType._TYPE); - private static _NAME = 'WKT Source'; - - static get TYPE(): string { - return WKTSourceType._TYPE; - } - static get ICON_URL(): string { - return WKTSourceType._ICON_URL; - } - static get NAME(): string { - return WKTSourceType._NAME; - } - - private type: ResultType; - private wkt: string; - - constructor(config: WKTSourceTypeConfig) { - super(); - this.type = config.type; - this.wkt = config.wkt; - } - - static fromDict(dict: WKTSourceTypeDict): WKTSourceType { - return new WKTSourceType({ - type: ResultTypes.fromCode(dict.type), - wkt: dict.wkt, - }); - } - - getMappingName(): string { - return WKTSourceType.TYPE; - } - - getIconUrl(): string { - return WKTSourceType.ICON_URL; - } - - toString(): string { - return WKTSourceType.NAME; - } - - getParametersAsStrings(): Array<[string, string]> { - return [ - ['type', this.type.toString()], - ['wkt', this.wkt.toString()], - ]; - } - - toMappingDict(): WKTSourceTypeMappingDict { - return { - type: this.type.getCode(), - wkt: this.wkt, - }; - } - - toDict(): WKTSourceTypeDict { - return { - operatorType: WKTSourceType.TYPE, - type: this.type.getCode(), - wkt: this.wkt, - }; - } - - cloneWithModifications(options?: {}): OperatorType { - return WKTSourceType.fromDict(this.toDict()); // TODO: add modifications - } -} diff --git a/projects/wave-core/src/lib/operators/unit.model.ts b/projects/wave-core/src/lib/operators/unit.model.ts deleted file mode 100644 index 5e3dae77..00000000 --- a/projects/wave-core/src/lib/operators/unit.model.ts +++ /dev/null @@ -1,283 +0,0 @@ -import {Map as ImmutableMap} from 'immutable'; - -/** - * A unit can have three types of interpolation between values. - * * Unknown - no information about interpolation between values - * * Continuous - it is okay to (linearly) scale in between values - * * Discrete - the unit states discrete values, e.g. for a classification - */ -export const enum Interpolation { - Unknown = 0, - Continuous = 1, - Discrete = 2, -} - -/** - * String serialization for interpolation variants - */ -export function interpolationToName(interpolation: Interpolation): string { - 'use strict'; - switch (interpolation) { - case Interpolation.Unknown: - return 'unknown'; - case Interpolation.Continuous: - return 'continuous'; - case Interpolation.Discrete: - return 'discrete'; - default: - throw new Error('Unknown Unit Interpolation'); - } -} - -/** - * String deserialization for interpolation variants - */ -export function nameToInterpolation(name: string): Interpolation { - 'use strict'; - if (name === interpolationToName(Interpolation.Continuous)) { - return Interpolation.Continuous; - } - if (name === interpolationToName(Interpolation.Discrete)) { - return Interpolation.Discrete; - } - return Interpolation.Unknown; -} - -/** - * A name of a classification value - */ -type Class = string; - -/** - * Input of the unit constructor. - */ -export interface UnitConfig { - measurement: string; - unit: string; - min?: number; - max?: number; - interpolation: Interpolation; - classes?: Map | ImmutableMap; -} - -/** - * Serialization of the unit for storage - */ -export interface UnitDict { - measurement: string; - unit: string; - min?: number; - max?: number; - interpolation: number; - classes: {[index: number]: string}; -} - -/** - * Serialization of a unit for queries to the backend - */ -export interface UnitMappingDict { - measurement: string; - unit: string; - min?: number; - max?: number; - interpolation: string; - classes?: {[index: number]: string}; -} - -/** - * A Unit contains semantical information about a set of values (i.e. a raster's pixels or an - * attribute). - * - * These are: - * - What is measured? e.g. Temperature, Elevation, Precipitation, ... - * - What unit is the measurement in? e.g. Celsius, Kelvin, Meters, cm/day, ... - * - Does it have a minimum or maximum value? - * - is it a continuous or a discrete value (e.g. temperature vs. classification)? - * - an optional set of parameters, e.g. names for a classification's classes - * - * Units can suggest a default colorization. - */ -export class Unit { - private static _defaultUnit = new Unit({ - measurement: 'unknown', - unit: 'unknown', - interpolation: Interpolation.Continuous, - }); - - private _measurement: string; - private _unit: string; - private _min: number; - private _max: number; - private _interpolation: Interpolation; - private _classes: ImmutableMap; - - /** - * Create a new unit with all parameters specified upfront - */ - constructor(config: UnitConfig) { - this._measurement = config.measurement; - this._unit = config.unit; - this._min = config.min; - this._max = config.max; - this._interpolation = config.interpolation; - if (config.classes) { - if (config.classes instanceof ImmutableMap) { - this._classes = config.classes as ImmutableMap; - } else { - this._classes = ImmutableMap(config.classes as Map); - } - } - } - - /** - * Deserialize a unit from a `UnitDict` - */ - static fromDict(dict: UnitDict): Unit { - let classes = new Map(); - if (dict.classes !== undefined) { - for (let className in dict.classes) { - classes.set(parseFloat(className), dict.classes[className]); - } - } - let config: UnitConfig = { - measurement: dict.measurement, - unit: dict.unit, - min: dict.min, - max: dict.max, - interpolation: dict.interpolation, - classes: classes, - }; - return new Unit(config); - } - - /** - * Deserialize a unit from unit information from the backend - */ - static fromMappingDict(dict: UnitMappingDict): Unit { - let interpolation = !!dict.interpolation ? nameToInterpolation(dict.interpolation) : Interpolation.Unknown; - let classes = new Map(); - if (dict.classes !== undefined) { - if (interpolation === Interpolation.Unknown) { - interpolation = Interpolation.Discrete; - } - for (let className in dict.classes) { - classes.set(parseFloat(className), dict.classes[className]); - } - } - let config: UnitConfig = { - measurement: dict.measurement, - unit: dict.unit, - min: dict.min, - max: dict.max, - interpolation: interpolation, - classes: classes, - }; - return new Unit(config); - } - - /** - * Default unit without further information (=> unitless) - */ - static get defaultUnit(): Unit { - return Unit._defaultUnit; - } - - /** - * What do the values measures? - */ - get measurement(): string { - return this._measurement; - } - - /** - * What is the unit of the measured values? - */ - get unit(): string { - return this._unit; - } - - /** - * Return a minimum value for this unit - */ - get min(): number { - return this._min; - } - - /** - * Return a maximum value for this unit - */ - get max(): number { - return this._max; - } - - /** - * Return the interpolation for this unit - */ - get interpolation(): Interpolation { - return this._interpolation; - } - - /** - * Return a map of classes of this unit. - * This is empty if the unit is no classification. - */ - get classes(): ImmutableMap { - return this._classes; - } - - /** - * Human-readable, concise string serialization of a unit - */ - toString(): string { - const output = []; - if (this.measurement !== 'unknown') { - output.push(this.measurement); - - if (this.unit !== 'unknown') { - output.push(` (${this.unit})`); - } - } - return output.join(''); - } - - /** - * Serialize the unit for storage - */ - toDict(): UnitDict { - let classes: { - [index: number]: string; - } = this._classes === undefined ? {} : (this._classes.toJS() as {[index: number]: string}); - - return { - measurement: this._measurement, - unit: this._unit, - min: this._min, - max: this._max, - interpolation: this._interpolation, - classes: classes, - }; - } - - /** - * Serialize the unit for queries to the backend - */ - toMappingDict(): UnitMappingDict { - let dict: UnitMappingDict = { - measurement: this._measurement, - unit: this._unit, - interpolation: interpolationToName(this._interpolation), - }; - - if (this._min !== undefined) { - dict.min = this._min; - } - if (this._max !== undefined) { - dict.max = this._max; - } - if (this._unit === 'classification') { - dict['classes'] = this._classes.toJS() as {[index: number]: string}; - } - - return dict; - } -} diff --git a/projects/wave-core/src/lib/plots/histogram/histogram.component.html b/projects/wave-core/src/lib/plots/histogram/histogram.component.html deleted file mode 100644 index 2a37c09f..00000000 --- a/projects/wave-core/src/lib/plots/histogram/histogram.component.html +++ /dev/null @@ -1,3 +0,0 @@ -
    - -
    diff --git a/projects/wave-core/src/lib/plots/histogram/histogram.component.scss b/projects/wave-core/src/lib/plots/histogram/histogram.component.scss deleted file mode 100644 index 00fae4ee..00000000 --- a/projects/wave-core/src/lib/plots/histogram/histogram.component.scss +++ /dev/null @@ -1,76 +0,0 @@ -:host { - display: block; -} - -:host .histogram ::ng-deep .chartbg { - fill: transparent; -} - -:host .histogram ::ng-deep .container { - fill: white; -} - -:host .histogram ::ng-deep .chart { - font: 10px sans-serif; -} - -:host .histogram ::ng-deep .bar rect { - fill: steelblue; - shape-rendering: crispEdges; -} - -:host .histogram ::ng-deep .lines rect { - fill: #ff0000; - shape-rendering: crispEdges; -} - -:host .histogram ::ng-deep .lines text { - fill: #ff0000; -} - -:host .histogram ::ng-deep .bar text { - fill: #fff; -} - -:host .histogram ::ng-deep .axis path, -.axis line { - fill: none; - stroke: #000; - shape-rendering: crispEdges; -} - -/* taken from http://bl.ocks.org/Caged/6476579 */ - -:host .histogram ::ng-deep .d3-tip { - line-height: 1; - font-weight: bold; - padding: 12px; - background: rgba(0, 0, 0, 0.8); - color: #fff; - border-radius: 2px; -} - -/* Creates a small triangle extender for the tooltip */ -:host .histogram ::ng-deep .d3-tip:after { - box-sizing: border-box; - display: inline; - font-size: 10px; - width: 100%; - line-height: 1; - color: rgba(0, 0, 0, 0.8); - content: '25BC'; - position: absolute; - text-align: center; -} - -/* Style northward tooltips differently */ -:host .histogram ::ng-deep .d3-tip.n:after { - margin: -1px 0 0 0; - top: 100%; - left: 0; -} - -.histogram_container { - width: 100%; - height: 100%; -} diff --git a/projects/wave-core/src/lib/plots/histogram/histogram.component.ts b/projects/wave-core/src/lib/plots/histogram/histogram.component.ts deleted file mode 100644 index 881e32c9..00000000 --- a/projects/wave-core/src/lib/plots/histogram/histogram.component.ts +++ /dev/null @@ -1,553 +0,0 @@ -import { - Component, - ChangeDetectionStrategy, - Input, - Output, - AfterViewInit, - EventEmitter, - ViewChild, - ElementRef, - OnChanges, - SimpleChange, - OnDestroy, -} from '@angular/core'; - -import {LayoutService} from '../../layout.service'; -import {fromEvent as observableFromEvent, Subscription} from 'rxjs'; -import {debounceTime, filter} from 'rxjs/operators'; -import {Config} from '../../config.service'; -import * as d3 from 'd3'; - -/** - * Schema for histogram data. - */ -export interface HistogramData { - type: string; // histogram - data: Array; - lines?: Array<{name: string; pos: number}>; - metadata: { - numberOfBuckets: number; - min: number; - max: number; - nodata: number; - unit: string; - }; -} - -/** - * Helper class for slider dimension - */ -interface SliderDim { - width: number; - height: number; - margin: { - top: number; - bottom: number; - }; -} - -/** - * Helper interface for a slider - */ -interface Slider { - area: d3.Selection; - pointer: d3.Selection; - text: d3.Selection; - position: number; -} - -/** - * This component displays a histogram plot response as a d3 graph. - */ -@Component({ - selector: 'wave-histogram', - templateUrl: `histogram.component.html`, - styleUrls: [`histogram.component.scss`], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class HistogramComponent implements AfterViewInit, OnChanges, OnDestroy { - @ViewChild('svg', {static: true}) svgRef: ElementRef; - - /** - * The histogram data from the backend response - */ - @Input() data: HistogramData; - - /** - * The height of the plot - */ - @Input() height: number; - - /** - * The width of the plot - */ - @Input() width: number; - - /** - * A scaling factor for width and height - */ - @Input() viewBoxRatio = 1; - - /** - * If set to true, users can select an interval within the histogram - */ - @Input() selectable = false; - - /** - * If set to true, users can zoom and pan within the graph - */ - @Input() interactable = false; - - /** - * If set to true, the component will call its event emitter upfront - */ - @Input() emmitInitialDataMinMax = false; - - /** - * If set to true, the component will react on resize events of the browser and redraw automatically. - */ - @Input() autoResize = false; - - /** - * Specify the minimum of the selection interval - */ - @Input() minRange: number = undefined; - - /** - * Emit events when the user selection (min) changes - */ - @Output() minRangeChange = new EventEmitter(); - - /** - * Specify the maximum of the selection interval - */ - @Input() maxRange: number = undefined; - - /** - * Emit events when the user selection (max) changes - */ - @Output() maxRangeChange = new EventEmitter(); - - private leftSlider: Slider; - private rightSlider: Slider; - private xAxis: d3.Axis; - private maxWidth: number; - private windowEventSubscription: Subscription; - - /** - * DI for services - */ - constructor(private elementRef: ElementRef, private config: Config) {} - - private static makeArea(xSlider: d3.Selection, height: number): d3.Selection { - return xSlider.append('rect').attr('x', 0).attr('width', 0).attr('height', height).attr('fill-opacity', 0.2); - } - - private static makePointer( - xSlider: d3.Selection, - height: number, - sliderDim: SliderDim, - xPosition: number, - ): d3.Selection { - return xSlider - .append('rect') - .attr('y', height + sliderDim.margin.top) - .attr('x', xPosition) - .attr('width', sliderDim.width) - .attr('height', sliderDim.height) - .attr('transform', 'translate(' + -(sliderDim.width / 2) + ',0)'); - } - - private static makeText( - xSlider: d3.Selection, - height: number, - sliderDim: SliderDim, - xPosition: number, - value: number, - ): d3.Selection { - return xSlider - .append('text') - .text(value.toFixed(2)) - .attr('x', xPosition - sliderDim.width / 2 + 5) - .attr('y', sliderDim.margin.top + height + sliderDim.height + sliderDim.margin.bottom); - } - - ngOnDestroy(): void { - if (this.windowEventSubscription) { - this.windowEventSubscription.unsubscribe(); - } - } - - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { - if (changes['data'] && !changes['data'].isFirstChange()) { - // clean up histogram - this.clearHistogram(); - - // draw new one - this.drawHistogram(); - if (this.emmitInitialDataMinMax) { - this.minRangeChange.emit(this.data.metadata.min); - this.maxRangeChange.emit(this.data.metadata.max); - } - } - // TODO: refactor the set slider position function out (here and in makeDrag) - if (changes['minRange'] && !changes['minRange'].isFirstChange()) { - const value = changes['minRange'].currentValue; - const xPosition = Math.max(this.xAxis.scale()(value), 0); - this.leftSlider.pointer.attr('x', xPosition); - this.leftSlider.position = value; - this.leftSlider.text.attr('x', xPosition); - this.leftSlider.text.text(value); - this.leftSlider.area.attr('width', xPosition); - } - if (changes['maxRange'] && !changes['maxRange'].isFirstChange()) { - const value = changes['maxRange'].currentValue; - const xPosition = Math.min(this.xAxis.scale()(value), this.maxWidth); - this.rightSlider.pointer.attr('x', xPosition); - this.rightSlider.position = value; - this.rightSlider.text.attr('x', xPosition); - this.rightSlider.text.text(value); - this.rightSlider.area.attr('width', this.maxWidth - xPosition); - this.rightSlider.area.attr('x', xPosition); - } - } - - private clearHistogram() { - d3.select(this.svgRef.nativeElement).select('g').remove(); - } - - ngAfterViewInit() { - if (!this.width || !this.height) { - this.calculateHistogramWidthAndHeight(); - } - - if (this.data) { - this.drawHistogram(); - if (this.emmitInitialDataMinMax) { - this.minRangeChange.emit(this.data.metadata.min); - this.maxRangeChange.emit(this.data.metadata.max); - } - } - this.windowEventSubscription = observableFromEvent(window, 'resize') - .pipe( - filter((_) => this.autoResize), - debounceTime(this.config.DELAYS.DEBOUNCE), - ) - .subscribe(() => { - this.clearHistogram(); - this.calculateHistogramWidthAndHeight(); - this.drawHistogram(); - }); - } - - private drawHistogram() { - const drawLines: boolean = this.data.lines !== undefined; - - const maxDigitsOnYAxis = Math.max(...this.data.data.map((v) => (v > 9 ? Math.ceil(Math.log10(v)) : 1))); - - const xAxisTextPadding = 5; - const xAxisTextHeight = 10 + xAxisTextPadding; - - const margin = { - top: 10, - right: 50, - bottom: 30 + (this.data.metadata.unit ? xAxisTextHeight : 0) + (this.selectable ? 35 : 0), - left: 12 * maxDigitsOnYAxis + 25, - }; - - const width = this.width * this.viewBoxRatio - margin.left - margin.right; - this.maxWidth = width; - const height = this.height * this.viewBoxRatio - margin.top - margin.bottom; - - const x = d3.scaleLinear().domain([this.data.metadata.min, this.data.metadata.max]).range([0, width]); - - const y = d3 - .scaleLinear() - .domain([0, d3.max(this.data.data)]) - .range([height, 0]); - - const xAxis = d3.axisBottom(x); - this.xAxis = xAxis; - - const yAxis = d3.axisLeft(y).tickFormat(d3.format('d')); // allow only integer ticks - - const svg = d3 - .select(this.svgRef.nativeElement) - .attr('width', this.width) - .attr('height', this.height) - .attr('viewBox', [0, 0, this.width * this.viewBoxRatio, this.height * this.viewBoxRatio].join(' ')) - .append('g') - .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - const container = svg.append('g').classed('container', true); - - const barWidth = width / this.data.metadata.numberOfBuckets; - - const bar = container - .selectAll('.bar') - .data(this.data.data) - .enter() - .append('g') - .classed('bar', true) - .attr('transform', (d, i) => { - const xPos = i * barWidth; - return `translate(${xPos},0)`; - }); - - bar.append('rect') - .attr('height', (d) => { - return height - y(d); - }) - .attr('width', barWidth > 1 ? barWidth - 1 : barWidth) - .attr('transform', (d, _i) => { - const yTrans = y(d); - return `translate(0,${yTrans})`; - }); - - /* draw vertical lines */ - if (drawLines) { - const lineContainer = container.append('g'); - const lines = lineContainer.selectAll('.lines').data(this.data.lines).enter().append('g').attr('class', 'lines'); - lines - .append('rect') - .attr('x', (d) => { - return x(d.pos); - }) // position() - .attr('y', y(0) - height) - .attr('height', height) - .attr('width', 1); - - lines - .append('text') - .attr('x', (d) => { - return x(d.pos) + 5; - }) // position() - .attr('y', y(0) - height + 20) - .text((d) => { - return d.name; - }); - } - - const borders = svg.append('g').attr('transform', `translate(${-margin.left},${-margin.top})`); - - borders.append('rect').attr('width', margin.left).attr('height', this.height).attr('fill', 'white'); - - borders - .append('rect') - .attr('x', margin.left + width) - .attr('height', this.height) - .attr('width', margin.left) - .attr('fill', 'white'); - - svg.append('g').attr('class', 'x axis').attr('transform', `translate(0,${height})`).call(xAxis); - - if (this.data.metadata.unit) { - svg.append('g') - .append('text') // x axis label - .attr('x', width / 2) - .attr('y', height + margin.bottom - xAxisTextPadding) - .style('text-anchor', 'middle') - .text(this.data.metadata.unit); - } - - svg.append('g').attr('class', 'y axis').call(yAxis); - - svg.append('text') // y axis label - .attr('transform', 'rotate(-90)') - .attr('y', -margin.left) - .attr('x', -height / 2) - .attr('dy', '1em') - .style('text-anchor', 'middle') - .text('Frequency'); - - let zoom: d3.ZoomBehavior; - if (this.selectable) { - // sliders to select a range - - const sliderDim: SliderDim = { - width: 10, - height: 20, - margin: { - top: 20, - bottom: 10, - }, - }; - - const xSlider = svg.append('g'); - - const leftSlider: Slider = { - area: HistogramComponent.makeArea(xSlider, height), - pointer: HistogramComponent.makePointer(xSlider, height, sliderDim, 0), - text: HistogramComponent.makeText(xSlider, height, sliderDim, 0, this.data.metadata.min), - position: this.data.metadata.min, - }; - this.leftSlider = leftSlider; - - const rightSlider: Slider = { - area: HistogramComponent.makeArea(xSlider, height), - pointer: HistogramComponent.makePointer(xSlider, height, sliderDim, width), - text: HistogramComponent.makeText(xSlider, height, sliderDim, width, this.data.metadata.max), - position: this.data.metadata.max, - }; - this.rightSlider = rightSlider; - - const leftDrag = this.makeDrag(xAxis, leftSlider, leftSlider, rightSlider, width, true); - const rightDrag = this.makeDrag(xAxis, rightSlider, leftSlider, rightSlider, width, false); - leftSlider.pointer.call(leftDrag); - rightSlider.pointer.call(rightDrag); - - // zoom - if (this.interactable) { - zoom = d3 - .zoom() - .scaleExtent([1, 10]) - .on('zoom', this.sliderZoomed(svg, container, xAxis, height, width, leftSlider, rightSlider)); - } - } else { - if (this.interactable) { - zoom = d3.zoom().scaleExtent([1, 10]).on('zoom', this.zoomed(svg, container, xAxis)); - } - } - - const chartbg = svg.append('rect').attr('class', 'chartbg').attr('width', width).attr('height', height); - - if (this.interactable) { - chartbg.call(zoom); - } - } - - private zoomed( - svg: d3.Selection, - container: d3.Selection, - xAxis: d3.Axis, - ): (zoomEvent: d3.D3ZoomEvent) => void { - return (zoomEvent) => { - container.attr('transform', `translate(${zoomEvent.transform.x},0)scale(${zoomEvent.transform.k},1)`); - svg.select('.x.axis').call(xAxis); - }; - } - - private sliderZoomed( - svg: d3.Selection, - container: d3.Selection, - xAxis: d3.Axis, - _height: number, - width: number, - leftSlider: Slider, - rightSlider: Slider, - ): (zoomEvent: d3.D3ZoomEvent) => void { - return (zoomEvent) => { - this.zoomed(svg, container, xAxis)(zoomEvent); - - // set left slider - const leftPointerPosition = clamp(xAxis.scale()(leftSlider.position), 0, width); - leftSlider.area.attr('width', leftPointerPosition); - leftSlider.pointer.attr('x', leftPointerPosition); - leftSlider.text.attr('x', leftPointerPosition); - - // set right slider - const rightPointerPosition = clamp(xAxis.scale()(rightSlider.position), 0, width); - rightSlider.area.attr('width', width - rightPointerPosition); - rightSlider.area.attr('x', rightPointerPosition); - rightSlider.pointer.attr('x', rightPointerPosition); - rightSlider.text.attr('x', rightPointerPosition); - }; - } - - private makeDrag( - xAxis: d3.Axis, - slider: Slider, - leftSlider: Slider, - rightSlider: Slider, - width: number, - isLeft: boolean, - ): d3.DragBehavior { - return d3.drag().on('drag', (dragEvent: d3.D3DragEvent) => { - const minX = this.data.metadata.min; - const maxX = this.data.metadata.max; - const bins = this.data.metadata.numberOfBuckets; - - const eventX = dragEvent.x; - - let lowerbound: number; - let upperbound: number; - if (isLeft) { - if (xAxis.scale()(minX) > 0) { - lowerbound = xAxis.scale()(minX); - } else { - lowerbound = 0; - } - } else { - lowerbound = xAxis.scale()(leftSlider.position) + 1; - } - if (!isLeft) { - if (xAxis.scale()(maxX) < width) { - upperbound = xAxis.scale()(maxX); - } else { - upperbound = width; - } - } else { - upperbound = xAxis.scale()(rightSlider.position) - 1; - } - - let newX: number; - if (eventX > lowerbound && eventX < upperbound) { - newX = eventX; - } else if (eventX <= lowerbound) { - newX = lowerbound; - } else { - newX = upperbound; - } - - // snap to closest bar - let newXVal = (xAxis.scale() as d3.ScaleLinear).invert(newX); - const bw = (maxX - minX) / bins; - const n = Math.round((newXVal - minX) / bw); - newX = xAxis.scale()(minX + n * bw); - newXVal = (xAxis.scale() as d3.ScaleLinear).invert(newX); - - slider.pointer.attr('x', newX); - slider.position = newXVal; - slider.text.attr('x', newX); - slider.text.text(newXVal); - if (isLeft) { - this.minRange = newXVal; - this.minRangeChange.emit(this.minRange); - } else { - this.maxRange = newXVal; - this.maxRangeChange.emit(this.maxRange); - } - if (isLeft) { - if (newX > 0) { - slider.area.attr('width', newX); - } else { - slider.area.attr('width', 0); - } - } else { - slider.area.attr('width', width - newX); - slider.area.attr('x', newX); - } - }); - } - - private calculateHistogramWidthAndHeight() { - const queryElem = this.elementRef.nativeElement.querySelector('div'); - const panelWidth = queryElem.clientWidth - 2 * LayoutService.remInPx; - const panelheight = queryElem.clientHeight - 2 * LayoutService.remInPx; - this.width = panelWidth; - this.height = Math.max(panelheight / 3, panelWidth / 3); - } -} - -/** - * Restrict a value to the interval [min, max] - */ -function clamp(value: number, min: number, max: number): number { - if (value <= min) { - return min; - } else if (value >= max) { - return max; - } else { - return value; - } -} diff --git a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-numeric-details/layer-statistics-numeric-details.component.html b/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-numeric-details/layer-statistics-numeric-details.component.html deleted file mode 100644 index b3bf824c..00000000 --- a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-numeric-details/layer-statistics-numeric-details.component.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - -
    Count{{ data.count }}
    NaN Count{{ data.nan_count }}
    Min{{ data.min }}
    Max{{ data.max }}
    Mean{{ data.mean }}
    Std. Dev.{{ data.stddev }}
    diff --git a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-numeric-details/layer-statistics-numeric-details.component.scss b/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-numeric-details/layer-statistics-numeric-details.component.scss deleted file mode 100644 index ae9d2df6..00000000 --- a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-numeric-details/layer-statistics-numeric-details.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -th, -td { - text-align: left; -} diff --git a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-numeric-details/layer-statistics-numeric-details.component.ts b/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-numeric-details/layer-statistics-numeric-details.component.ts deleted file mode 100644 index acb6d245..00000000 --- a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-numeric-details/layer-statistics-numeric-details.component.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy, Input} from '@angular/core'; - -export interface NumericStatisticsData { - count: number; - nan_count: number; - min: number; - max: number; - mean: number; - stddev: number; -} - -@Component({ - selector: 'wave-layer-statistics-numeric-details', - templateUrl: './layer-statistics-numeric-details.component.html', - styleUrls: ['./layer-statistics-numeric-details.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LayerStatisticsNumericDetailsComponent implements OnInit { - @Input() - data: NumericStatisticsData; - - constructor() {} - - ngOnInit() {} -} diff --git a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-textual-details/layer-statistics-textual-details.component.html b/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-textual-details/layer-statistics-textual-details.component.html deleted file mode 100644 index 1f3b2c53..00000000 --- a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-textual-details/layer-statistics-textual-details.component.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - -
    Count{{ data.count }}
    Distinct Values{{ data.distinct_values }}
    - - - - - - - - - - - - -
    ValueCount
    {{ item[0] }}{{ item[1] }}
    diff --git a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-textual-details/layer-statistics-textual-details.component.scss b/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-textual-details/layer-statistics-textual-details.component.scss deleted file mode 100644 index ae9d2df6..00000000 --- a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-textual-details/layer-statistics-textual-details.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -th, -td { - text-align: left; -} diff --git a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-textual-details/layer-statistics-textual-details.component.ts b/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-textual-details/layer-statistics-textual-details.component.ts deleted file mode 100644 index 9d9c6c8a..00000000 --- a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-textual-details/layer-statistics-textual-details.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy, Input} from '@angular/core'; - -export interface TextualStatisticsData { - count: number; - distinct_values: number; - value_counts: Array<[string, number]>; -} - -@Component({ - selector: 'wave-layer-statistics-textual-details', - templateUrl: './layer-statistics-textual-details.component.html', - styleUrls: ['./layer-statistics-textual-details.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LayerStatisticsTextualDetailsComponent implements OnInit { - @Input() - data: TextualStatisticsData; - - constructor() {} - - ngOnInit() {} -} diff --git a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-view.component.html b/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-view.component.html deleted file mode 100644 index febb4351..00000000 --- a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-view.component.html +++ /dev/null @@ -1,58 +0,0 @@ -
    -

    Raster Layer Statistics

    - -

    Raster {{ i + 1 }}

    - -
    -
    -
    -

    Point Layer Statistics

    - -

    Points {{ i + 1 }}

    - -

    {{ featureData.key }}

    - - -
    -
    -
    -
    -

    Line Layer Statistics

    - -

    Points {{ i + 1 }}

    - -

    {{ featureData.key }}

    - - -
    -
    -
    -
    -

    Polygon Layer Statistics

    - -

    Points {{ i + 1 }}

    - -

    {{ featureData.key }}

    - - -
    -
    -
    diff --git a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-view.component.scss b/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-view.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-view.component.ts b/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-view.component.ts deleted file mode 100644 index 2af04f6c..00000000 --- a/projects/wave-core/src/lib/plots/layer-statistics-view/layer-statistics-view.component.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy, Input} from '@angular/core'; -import {NumericStatisticsData} from './layer-statistics-numeric-details/layer-statistics-numeric-details.component'; -import {TextualStatisticsData} from './layer-statistics-textual-details/layer-statistics-textual-details.component'; - -interface LayerStatisticsData { - rasters?: Array; - points?: Array; - lines?: Array; - polygons?: Array; -} - -interface FeatureData { - [name: string]: NumericStatisticsData | TextualStatisticsData; -} - -@Component({ - selector: 'wave-layer-statistics-view', - templateUrl: './layer-statistics-view.component.html', - styleUrls: ['./layer-statistics-view.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LayerStatisticsViewComponent implements OnInit { - @Input() - public data: LayerStatisticsData; - - constructor() {} - - ngOnInit() {} -} diff --git a/projects/wave-core/src/lib/plots/plot-detail-view/plot-detail-view.component.html b/projects/wave-core/src/lib/plots/plot-detail-view/plot-detail-view.component.html deleted file mode 100644 index a7faf459..00000000 --- a/projects/wave-core/src/lib/plots/plot-detail-view/plot-detail-view.component.html +++ /dev/null @@ -1,29 +0,0 @@ -{{ plot.name }} - - -
    {{ (projectService.getPlotDataStream(plot) | async)?.data }}
    -
    - - - - - - - - - - - - -
    {{ (projectService.getPlotDataStream(plot) | async)?.data | json }}
    -
    - -
    {{ (projectService.getPlotDataStream(plot) | async)?.data }}
    -
    -
    diff --git a/projects/wave-core/src/lib/plots/plot-detail-view/plot-detail-view.component.scss b/projects/wave-core/src/lib/plots/plot-detail-view/plot-detail-view.component.scss deleted file mode 100644 index 684b32c1..00000000 --- a/projects/wave-core/src/lib/plots/plot-detail-view/plot-detail-view.component.scss +++ /dev/null @@ -1,8 +0,0 @@ -wave-histogram { - background-color: white; -} - -mat-dialog-content { - max-height: unset; - max-width: unset; -} diff --git a/projects/wave-core/src/lib/plots/plot-detail-view/plot-detail-view.component.ts b/projects/wave-core/src/lib/plots/plot-detail-view/plot-detail-view.component.ts deleted file mode 100644 index fe272e07..00000000 --- a/projects/wave-core/src/lib/plots/plot-detail-view/plot-detail-view.component.ts +++ /dev/null @@ -1,73 +0,0 @@ -import {ReplaySubject, BehaviorSubject, combineLatest as observableCombineLatest} from 'rxjs'; -import {first} from 'rxjs/operators'; - -import {AfterViewInit, ChangeDetectionStrategy, Component, Inject, OnInit} from '@angular/core'; -import {MAT_DIALOG_DATA} from '@angular/material/dialog'; -import {ProjectService} from '../../project/project.service'; -import {Plot} from '../plot.model'; -import {LayoutService} from '../../layout.service'; -import {MappingQueryService} from '../../queries/mapping-query.service'; -import {MapService} from '../../map/map.service'; - -@Component({ - selector: 'wave-plot-detail-view', - templateUrl: './plot-detail-view.component.html', - styleUrls: ['./plot-detail-view.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class PlotDetailViewComponent implements OnInit, AfterViewInit { - maxWidth$ = new ReplaySubject(1); - maxHeight$ = new ReplaySubject(1); - - // initially blank pixel - imagePlotData$ = new BehaviorSubject('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='); - imagePlotLoading$ = new BehaviorSubject(true); - - constructor( - public projectService: ProjectService, - private mapService: MapService, - private mappingQueryService: MappingQueryService, - @Inject(MAT_DIALOG_DATA) public plot: Plot, - ) {} - - ngOnInit() { - observableCombineLatest( - this.projectService.getPlotDataStream(this.plot), - this.projectService.getTimeStream(), - this.projectService.getProjectionStream(), - this.mapService.getViewportSizeStream(), - this.maxWidth$, - this.maxHeight$, - ) - .pipe(first()) - .subscribe(([plotData, time, projection, viewport, width, height]) => { - // set data uri for png type and load full screen image - if (plotData.type === 'png') { - this.imagePlotData$.next(`data:image/png;base64,${plotData.data}`); - - this.mappingQueryService - .getPlotData({ - operator: this.plot.operator, - time: time, - extent: viewport.extent, - projection: projection, - plotWidth: width - LayoutService.remInPx, - plotHeight: height, - }) - .pipe(first()) - .subscribe((newPlotData) => { - this.imagePlotData$.next(`data:image/png;base64,${newPlotData.data}`); - - this.imagePlotLoading$.next(false); - }); - } - }); - } - - ngAfterViewInit() { - setTimeout(() => { - this.maxWidth$.next(window.innerWidth - 2 * LayoutService.remInPx); - this.maxHeight$.next(window.innerHeight - 2 * LayoutService.remInPx - LayoutService.getToolbarHeightPx()); - }); - } -} diff --git a/projects/wave-core/src/lib/plots/plot-list/plot-list.component.html b/projects/wave-core/src/lib/plots/plot-list/plot-list.component.html deleted file mode 100644 index 6fdf7e1e..00000000 --- a/projects/wave-core/src/lib/plots/plot-list/plot-list.component.html +++ /dev/null @@ -1,75 +0,0 @@ -Plots -

    - no plots available -
    - -

    - - - - {{ plot.name }} - {{ plot.operator.operatorType.toString() }} - - - - - - -
    {{ (projectService.getPlotDataStream(plot) | async)?.data }}
    -
    - - {{ plot.name }} - - - - - - - - -
    {{ (projectService.getPlotDataStream(plot) | async)?.data | json }}
    -
    - -
    {{ (projectService.getPlotDataStream(plot) | async)?.data }}
    -
    -
    - - - - - - - - - - - - -
    diff --git a/projects/wave-core/src/lib/plots/plot-list/plot-list.component.scss b/projects/wave-core/src/lib/plots/plot-list/plot-list.component.scss deleted file mode 100644 index e33d19c0..00000000 --- a/projects/wave-core/src/lib/plots/plot-list/plot-list.component.scss +++ /dev/null @@ -1,39 +0,0 @@ -:host { - display: block; - padding: 1rem; -} - -mat-card:not(:last-child) { - margin-bottom: 1rem; -} - -img { - width: 100%; - height: auto; -} - -img.mat-card-avatar { - height: 40px; - width: auto; - border-radius: 50%; -} - -pre { - overflow: hidden; -} - -mat-spinner { - width: 25%; - height: auto; - margin: 0 auto; -} - -.error { - color: var(--wave-warn-color, red); -} - -.no-plots { - color: var(--wave-foreground-secondary-text-color, grey); - margin-top: 50%; - text-align: center; -} diff --git a/projects/wave-core/src/lib/plots/plot-list/plot-list.component.ts b/projects/wave-core/src/lib/plots/plot-list/plot-list.component.ts deleted file mode 100644 index 603ba076..00000000 --- a/projects/wave-core/src/lib/plots/plot-list/plot-list.component.ts +++ /dev/null @@ -1,112 +0,0 @@ -import {BehaviorSubject, Subscription} from 'rxjs'; -import {first, filter} from 'rxjs/operators'; - -import {MatDialog} from '@angular/material/dialog'; -import {AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Input, OnDestroy, OnInit} from '@angular/core'; - -import {BoxPlotType} from '../../operators/types/boxplot-type.model'; -import {LayoutService} from '../../layout.service'; -import {LoadingState} from '../../project/loading-state.model'; -import {OperatorListComponent} from '../../operators/dialogs/operator-list/operator-list.component'; -import {PieChartType} from '../../operators/types/piechart-type.model'; -import {PlotDetailViewComponent} from '../plot-detail-view/plot-detail-view.component'; -import {Plot} from '../plot.model'; -import {ProjectService} from '../../project/project.service'; -import {ROperatorComponent} from '../../operators/dialogs/r/r-operator/r-operator.component'; -import {RScriptType} from '../../operators/types/r-script-type.model'; -import {ScatterPlotType} from '../../operators/types/scatterplot-type.model'; -import {TimePlotType} from '../../operators/types/timeplot-type.model'; - -/** - * This component lists all current plots. - */ -@Component({ - selector: 'wave-plot-list', - templateUrl: './plot-list.component.html', - styleUrls: ['./plot-list.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class PlotListComponent implements OnInit, AfterViewInit, OnDestroy { - /** - * If the list is empty, show the following button. - */ - @Input() operatorsListConfig = {component: OperatorListComponent}; - - readonly RScriptType = RScriptType; - readonly ScatterPlotType = ScatterPlotType; - readonly PieChartType = PieChartType; - readonly BoxPlotType = BoxPlotType; - readonly TimePlotType = TimePlotType; - readonly LoadingState = LoadingState; - - // to distinguish some r-script operators out of the editable ones. - readonly editExceptions = [this.ScatterPlotType.NAME, this.PieChartType.NAME, this.BoxPlotType.NAME, this.TimePlotType.NAME]; - readonly cardWidth$: BehaviorSubject = new BehaviorSubject(undefined); - - private subscriptions: Array = []; - - /** - * DI for services - */ - constructor( - public readonly projectService: ProjectService, - public readonly dialog: MatDialog, - private readonly layoutService: LayoutService, - private readonly elementRef: ElementRef, - ) {} - - ngOnInit() {} - - ngAfterViewInit() { - this.subscriptions.push( - this.projectService - .getPlotStream() - .pipe( - filter((plots) => plots.length > 0), - first(), - ) - .subscribe(() => { - setTimeout(() => { - const cardContent = this.elementRef.nativeElement.querySelector('mat-card'); - const width = parseInt(getComputedStyle(cardContent).width, 10); - this.cardWidth$.next(width); - }); - }), - ); - } - - ngOnDestroy() { - this.subscriptions.forEach((subscription) => subscription.unsubscribe()); - } - - /** - * If the plot is an RScript type, open the operator dialog for editing the source code. - */ - editRPlot(plot: Plot) { - this.layoutService.setSidenavContentComponent({ - component: ROperatorComponent, - keepParent: true, - config: { - editable: plot, - }, - }); - } - - /** - * Loads the component in `operatorsListConfig` into the sidenav - */ - goToOperatorsTab() { - this.layoutService.setSidenavContentComponent(this.operatorsListConfig); - } - - /** - * Show a plot as a fullscreen modal dialog - */ - showFullscreen(plot: Plot) { - this.dialog.open(PlotDetailViewComponent, { - data: plot, - maxHeight: '100vh', - maxWidth: '100vw', - }); - } -} diff --git a/projects/wave-core/src/lib/plots/plot.model.ts b/projects/wave-core/src/lib/plots/plot.model.ts deleted file mode 100644 index c17c27a1..00000000 --- a/projects/wave-core/src/lib/plots/plot.model.ts +++ /dev/null @@ -1,80 +0,0 @@ -import {Operator, OperatorDict} from '../operators/operator.model'; - -/** - * Schema for plot data. - */ -export interface PlotData { - type: string; - data: Array | string; - lines?: Array<{name: string; pos: number}>; - metadata?: { - numberOfBuckets?: number; - min?: number; - max?: number; - nodata?: number; - }; -} - -/** - * Dictionary for instantiating plot. - */ -interface PlotConfig { - name: string; - operator: Operator; -} - -/** - * Dictionary for serialization. - */ -export interface PlotDict { - name: string; - operator: OperatorDict; -} - -/** - * A model for plots and text outputs - */ -export class Plot { - private _name: string; - private _operator: Operator; - - /** - * De-Serialization - */ - static fromDict(dict: PlotDict, operatorMap = new Map()): Plot { - const operator = Operator.fromDict(dict.operator, operatorMap); - return new Plot({ - name: dict.name, - operator: operator, - }); - } - - constructor(config: PlotConfig) { - this._name = config.name; - this._operator = config.operator; - } - - /** - * @return the operator. - */ - get operator(): Operator { - return this._operator; - } - - /** - * @returns the data observable. - */ - get name(): string { - return this._name; - } - - /** - * Serialization - */ - toDict(): PlotDict { - return { - name: this.name, - operator: this.operator.toDict(), - }; - } -} diff --git a/projects/wave-core/src/lib/project/change-projection/change-projection.component.html b/projects/wave-core/src/lib/project/change-projection/change-projection.component.html deleted file mode 100644 index e9485c8b..00000000 --- a/projects/wave-core/src/lib/project/change-projection/change-projection.component.html +++ /dev/null @@ -1,10 +0,0 @@ -Change Projection -

    - Change the projection of the current project. Note, that this projection only has an impact on the final result. VAT processes all - intermediate steps with as few re-projections as necessary. -

    - - - {{ projection }} - - diff --git a/projects/wave-core/src/lib/project/change-projection/change-projection.component.scss b/projects/wave-core/src/lib/project/change-projection/change-projection.component.scss deleted file mode 100644 index 2e62f261..00000000 --- a/projects/wave-core/src/lib/project/change-projection/change-projection.component.scss +++ /dev/null @@ -1,13 +0,0 @@ -:host { - display: block; - padding: 1rem; -} - -p { - margin-bottom: 2rem; - text-align: justify; -} - -mat-form-field { - width: 100%; -} diff --git a/projects/wave-core/src/lib/project/change-projection/change-projection.component.ts b/projects/wave-core/src/lib/project/change-projection/change-projection.component.ts deleted file mode 100644 index 06240694..00000000 --- a/projects/wave-core/src/lib/project/change-projection/change-projection.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; -import {ProjectService} from '../project.service'; -import {Projections, Projection} from '../../operators/projection.model'; -import {Observable} from 'rxjs'; - -@Component({ - selector: 'wave-change-projection', - templateUrl: './change-projection.component.html', - styleUrls: ['./change-projection.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ChangeProjectionComponent implements OnInit { - readonly Projections = Projections; - - projection$: Observable; - - constructor(public projectService: ProjectService) {} - - ngOnInit() { - this.projection$ = this.projectService.getProjectionStream(); - } -} diff --git a/projects/wave-core/src/lib/project/load-project/load-project.component.html b/projects/wave-core/src/lib/project/load-project/load-project.component.html deleted file mode 100644 index b66d7698..00000000 --- a/projects/wave-core/src/lib/project/load-project/load-project.component.html +++ /dev/null @@ -1,10 +0,0 @@ -Load Project -
    - - - {{ name }}{{ name === currentProjectName ? ' (current)' : '' }} - - - -
    - diff --git a/projects/wave-core/src/lib/project/load-project/load-project.component.scss b/projects/wave-core/src/lib/project/load-project/load-project.component.scss deleted file mode 100644 index fcacec57..00000000 --- a/projects/wave-core/src/lib/project/load-project/load-project.component.scss +++ /dev/null @@ -1,27 +0,0 @@ -:host { - display: block; - padding: 1rem; - height: 100%; - box-sizing: border-box; -} - -form { - height: 100%; -} - -mat-radio-group { - overflow-y: auto; -} - -mat-radio-button { - display: block; -} - -button { - width: 100%; - margin-top: 2rem; -} - -mat-progress-spinner { - margin: 0 auto; -} diff --git a/projects/wave-core/src/lib/project/load-project/load-project.component.ts b/projects/wave-core/src/lib/project/load-project/load-project.component.ts deleted file mode 100644 index 5431d600..00000000 --- a/projects/wave-core/src/lib/project/load-project/load-project.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -import {BehaviorSubject, ReplaySubject} from 'rxjs'; -import {first} from 'rxjs/operators'; -import {Component, OnInit, ChangeDetectionStrategy, AfterViewInit} from '@angular/core'; -import {ProjectService} from '../project.service'; -import {StorageService} from '../../storage/storage.service'; -import {FormBuilder, FormGroup, Validators, AbstractControl, ValidatorFn} from '@angular/forms'; -import {NotificationService} from '../../notification.service'; - -function notCurrentProject(currentProjectName: () => string): ValidatorFn { - return (control: AbstractControl): {[key: string]: boolean} => { - const errors: { - currentProject?: boolean; - } = {}; - - if (currentProjectName() === control.value) { - errors.currentProject = true; - } - - return Object.keys(errors).length > 0 ? errors : null; - }; -} - -@Component({ - selector: 'wave-load-project', - templateUrl: './load-project.component.html', - styleUrls: ['./load-project.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class LoadProjectComponent implements OnInit, AfterViewInit { - form: FormGroup; - - projects$ = new ReplaySubject>(1); - loading$ = new BehaviorSubject(true); - - currentProjectName: string; - - constructor( - private projectService: ProjectService, - private storageService: StorageService, - private notificationService: NotificationService, - private formBuilder: FormBuilder, - ) {} - - ngOnInit() { - this.currentProjectName = ''; - this.projectService - .getProjectStream() - .pipe(first()) - .subscribe((project) => { - this.currentProjectName = project.name; - }); - - this.form = this.formBuilder.group({ - projectName: [ - this.currentProjectName, - Validators.compose([Validators.required, notCurrentProject(() => this.currentProjectName)]), - ], - }); - - this.storageService.getProjects().subscribe((projects) => { - this.projects$.next(projects); - this.loading$.next(false); - }); - } - - ngAfterViewInit() { - setTimeout(() => this.form.updateValueAndValidity()); - } - - load() { - const newProject: string = this.form.controls['projectName'].value; - this.storageService.loadProjectByName(newProject); - this.currentProjectName = newProject; - setTimeout(() => this.form.controls['projectName'].updateValueAndValidity({emitEvent: true})); - - this.notificationService.info(`Switched to project »${newProject}«`); - } -} diff --git a/projects/wave-core/src/lib/project/loading-state.model.ts b/projects/wave-core/src/lib/project/loading-state.model.ts deleted file mode 100644 index f424efaf..00000000 --- a/projects/wave-core/src/lib/project/loading-state.model.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * A signal for the state of a async data observable. - */ -export enum LoadingState { - OK = 0, - LOADING = 1, - ERROR = 3, - NODATAFORGIVENTIME = 4, -} diff --git a/projects/wave-core/src/lib/project/new-project/new-project.component.html b/projects/wave-core/src/lib/project/new-project/new-project.component.html deleted file mode 100644 index 6ac08555..00000000 --- a/projects/wave-core/src/lib/project/new-project/new-project.component.html +++ /dev/null @@ -1,28 +0,0 @@ -New Project - -

    Create a new, blank project.

    -
    -
    - - - The name is already in usage. - -
    -
    - - - - {{ projection }} - - - -
    - -
    -
    - -

    - Created project {{ form.controls['name'].value }} and switched to it.

    - You are ready to go! -

    -
    diff --git a/projects/wave-core/src/lib/project/new-project/new-project.component.scss b/projects/wave-core/src/lib/project/new-project/new-project.component.scss deleted file mode 100644 index df9e83a6..00000000 --- a/projects/wave-core/src/lib/project/new-project/new-project.component.scss +++ /dev/null @@ -1,26 +0,0 @@ -:host { - display: block; - padding: 1rem; -} - -p { - text-align: justify; - margin-bottom: 2rem; -} - -.error { - color: var(--wave-warn-color, red); -} - -mat-form-field { - margin: 1rem 0; -} - -button { - margin-top: 1rem; - width: 100%; -} - -p.finished { - text-align: center; -} diff --git a/projects/wave-core/src/lib/project/new-project/new-project.component.ts b/projects/wave-core/src/lib/project/new-project/new-project.component.ts deleted file mode 100644 index 90e04e56..00000000 --- a/projects/wave-core/src/lib/project/new-project/new-project.component.ts +++ /dev/null @@ -1,74 +0,0 @@ -import {BehaviorSubject} from 'rxjs'; -import {first} from 'rxjs/operators'; -import {Component, OnInit, ChangeDetectionStrategy, AfterViewInit} from '@angular/core'; -import {FormGroup, FormBuilder, Validators} from '@angular/forms'; -import {StorageService} from '../../storage/storage.service'; -import {ProjectService} from '../project.service'; -import {Project} from '../project.model'; -import {Projections} from '../../operators/projection.model'; -import {NotificationService} from '../../notification.service'; -import {WaveValidators} from '../../util/form.validators'; - -@Component({ - selector: 'wave-new-project', - templateUrl: './new-project.component.html', - styleUrls: ['./new-project.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class NewProjectComponent implements OnInit, AfterViewInit { - // make available - Projections = Projections; - // - - form: FormGroup; - - created$ = new BehaviorSubject(false); - - constructor( - private formBuilder: FormBuilder, - private storageService: StorageService, - private projectService: ProjectService, - private notificationService: NotificationService, - ) {} - - ngOnInit() { - this.form = this.formBuilder.group({ - name: ['', Validators.required, WaveValidators.uniqueProjectName(this.storageService)], - projection: [Projections.WEB_MERCATOR, Validators.required], - }); - this.projectService - .getProjectionStream() - .pipe(first()) - .subscribe((projection) => { - this.form.controls['projection'].setValue(projection); - }); - } - - ngAfterViewInit() { - setTimeout(() => this.form.updateValueAndValidity()); - } - - /** - * Create a new project and switch to it. - */ - create() { - this.projectService - .getTimeStream() - .pipe(first()) - .subscribe((time) => { - const projectName: string = this.form.controls['name'].value; - this.projectService.setProject( - new Project({ - name: projectName, - projection: this.form.controls['projection'].value, - time: time, - layers: [], - timeStepDuration: {durationAmount: 1, durationUnit: 'months'}, - }), - ); - - this.created$.next(true); - this.notificationService.info(`Created and switched to new project »${projectName}«`); - }); - } -} diff --git a/projects/wave-core/src/lib/project/project.model.ts b/projects/wave-core/src/lib/project/project.model.ts deleted file mode 100644 index 433ccc0c..00000000 --- a/projects/wave-core/src/lib/project/project.model.ts +++ /dev/null @@ -1,189 +0,0 @@ -import {Projection, Projections} from '../operators/projection.model'; -import {Time, TimeDict, timeFromDict, TimePoint, TimeInterval, TimeStepDuration} from '../time/time.model'; -import {Plot, PlotDict} from '../plots/plot.model'; -import {Operator} from '../operators/operator.model'; -import {Config} from '../config.service'; -import {NotificationService} from '../notification.service'; -import {AbstractSymbology} from '../layers/symbology/symbology.model'; -import {Layer, LayerDict} from '../layers/layer.model'; - -export interface ProjectConfig { - name: string; - projection: Projection; - time: Time; - plots?: Array; - layers?: Array>; - timeStepDuration: TimeStepDuration; -} - -export interface ProjectDict { - name: string; - projection: string; - time: TimeDict; - plots: Array; - layers: Array; - timeStepDuration: TimeStepDuration; -} - -export class Project { - private _projection: Projection; - private _time: Time; - private _name: string; - private _plots: Array; - private _layers: Array>; - private _timeStepDuration: TimeStepDuration; - - static fromJSON(parameters: { - json: string; - config: Config; - notificationService: NotificationService; - operatorMap?: Map; - }): Project { - if (!parameters.operatorMap) { - parameters.operatorMap = new Map(); - } - - try { - const dict = JSON.parse(parameters.json); - return Project.fromDict({ - dict: dict, - config: parameters.config, - notificationService: parameters.notificationService, - operatorMap: parameters.operatorMap, - }); - } catch (error) { - parameters.notificationService.error(`Invalid JSON from project due to »${error}«`); - // return default project - return new Project({ - name: parameters.config.DEFAULTS.PROJECT.NAME, - projection: Projections.fromCode(parameters.config.DEFAULTS.PROJECT.PROJECTION), - time: new TimePoint(parameters.config.DEFAULTS.PROJECT.TIME), - plots: [], - layers: [], - timeStepDuration: {durationAmount: 1, durationUnit: 'months'}, // TODO: move to DEFAULTS! - }); - } - } - - static fromDict(parameters: { - dict: ProjectDict; - config: Config; - notificationService: NotificationService; - operatorMap?: Map; - }): Project { - if (!parameters.operatorMap) { - parameters.operatorMap = new Map(); - } - - let plots: Array; - if (parameters.dict.plots) { - plots = parameters.dict.plots - .map((plotDict) => { - try { - return Plot.fromDict(plotDict, parameters.operatorMap); - } catch (error) { - parameters.notificationService.error(`Cannot load plot because of »${error}«`); - return undefined; - } - }) - .filter((plot) => plot !== undefined); - } else { - plots = []; - } - - let projection: Projection; - try { - projection = Projections.fromCode(parameters.dict.projection); - } catch (error) { - projection = Projections.fromCode(parameters.config.DEFAULTS.PROJECT.PROJECTION); - parameters.notificationService.error(`Cannot load projection because of »${error}«`); - } - - let time: TimePoint | TimeInterval; - try { - time = timeFromDict(parameters.dict.time); - } catch (error) { - time = new TimePoint(parameters.config.DEFAULTS.PROJECT.TIME); - parameters.notificationService.error(`Cannot load time because of »${error}«`); - } - - let layers: Array>; - if (parameters.dict.layers) { - layers = parameters.dict.layers - .map((layerDict) => { - try { - return Layer.fromDict(layerDict, parameters.operatorMap); - } catch (error) { - parameters.notificationService.error(`Cannot load layer because of »${error}«`); - return undefined; - } - }) - .filter((layer) => layer !== undefined); - } else { - layers = []; - } - let timeStepDuration: TimeStepDuration; - if (parameters.dict.timeStepDuration) { - timeStepDuration = parameters.dict.timeStepDuration; - } else { - timeStepDuration = {durationAmount: 1, durationUnit: 'months'}; - } - - return new Project({ - name: parameters.dict.name, - projection: projection, - time: time, - plots: plots, - layers: layers, - timeStepDuration: timeStepDuration, - }); - } - - constructor(config: ProjectConfig) { - this._name = config.name; - this._projection = config.projection; - this._time = config.time; - this._plots = config.plots ? config.plots : []; - this._layers = config.layers ? config.layers : []; - this._timeStepDuration = config.timeStepDuration; - } - - get name(): string { - return this._name; - } - - get time(): Time { - return this._time; - } - - get projection(): Projection { - return this._projection; - } - - get plots(): Array { - return this._plots; - } - - get layers(): Array> { - return this._layers; - } - - get timeStepDuration(): TimeStepDuration { - return this._timeStepDuration; - } - - toDict(): ProjectDict { - return { - name: this.name, - projection: this._projection.getCode(), - time: this._time.asDict(), - plots: this._plots.map((plot) => plot.toDict()), - layers: this._layers.map((layer) => layer.toDict()), - timeStepDuration: this._timeStepDuration, - }; - } - - toJSON(): string { - return JSON.stringify(this.toDict()); - } -} diff --git a/projects/wave-core/src/lib/project/project.service.spec.ts b/projects/wave-core/src/lib/project/project.service.spec.ts deleted file mode 100644 index 595a75af..00000000 --- a/projects/wave-core/src/lib/project/project.service.spec.ts +++ /dev/null @@ -1,320 +0,0 @@ -import {configureWaveTesting} from '../spec/wave-testing.configuration'; -import {fakeAsync, TestBed, TestModuleMetadata, tick} from '@angular/core/testing'; -import {Config} from '../config.service'; -import {UserService} from '../users/user.service'; -import {NotificationService} from '../notification.service'; -import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; -import {ProjectService} from './project.service'; -import {MappingQueryService} from '../queries/mapping-query.service'; -import {clear_user_service_requests, MockBackend} from '../users/user.service.spec'; -import {LayerService} from '../layers/layer.service'; -import {LayoutService} from '../layout.service'; -import {ReplaySubject, Subject} from 'rxjs'; -import {Plot} from '../plots/plot.model'; -import {MapService} from '../map/map.service'; -import {RScriptTypeDict} from '../operators/types/r-script-type.model'; -import {Layer} from '../layers/layer.model'; -import {RasterSourceType} from '../operators/types/raster-source-type.model'; -import {RasterSymbologyDict} from '../layers/symbology/symbology.model'; - -class MockConfig { - static MOCK_URL = 'localhost:8089/mapping-mock'; - static MOCK_USER = { - GUEST: { - NAME: 'guest', - PASSWORD: 'guest', - }, - }; - - get MAPPING_URL(): string { - return MockConfig.MOCK_URL; - } - - get USER(): {GUEST: {NAME: string; PASSWORD: string}} { - return MockConfig.MOCK_USER; - } - - get DELAYS(): {LOADING: {MIN: number}; TOOLTIP: number; DEBOUNCE: number; STORAGE_DEBOUNCE: number; GUEST_LOGIN_HINT: number} { - return { - LOADING: { - MIN: 0, - }, - TOOLTIP: 5, - DEBOUNCE: 0, - STORAGE_DEBOUNCE: 0, - GUEST_LOGIN_HINT: 5, - }; - } - - get DEFAULTS(): { - PROJECT: { - NAME: string; - TIME: string; - TIMESTEP: '15 minutes' | '1 hour' | '1 day' | '1 month' | '6 months' | '1 year'; - PROJECTION: 'EPSG:3857' | 'EPSG:4326'; - }; - } { - return { - PROJECT: { - NAME: 'DEFAULT', - TIME: '2000-01-01T00:00:00', - TIMESTEP: '1 hour', - PROJECTION: 'EPSG:3857', - }, - }; - } -} - -class MockNotificationService { - info(message: string) {} - error(message: string) {} -} - -class MockLayoutService { - private sidenavContentMaxWidth$: Subject = new ReplaySubject(1); - - constructor() { - this.sidenavContentMaxWidth$.next(200); - } - - getSidenavWidthStream() { - return this.sidenavContentMaxWidth$; - } -} - -const module = { - providers: [ - {provide: Config, useClass: MockConfig}, - {provide: NotificationService, useClass: MockNotificationService}, - LayerService, - {provide: LayoutService, useClass: MockLayoutService}, - MapService, - UserService, - MappingQueryService, - ProjectService, - ], - imports: [HttpClientTestingModule], -} as TestModuleMetadata; - -function login(http: HttpTestingController, backend: MockBackend) { - clear_user_service_requests(http); - - expect(http.match((req) => true).length).toBe(0); - - let user = TestBed.inject(UserService); - - let completed = null; - user.login({user: 'test', password: 'test_pw'}).subscribe( - (login_response) => { - expect(login_response).toBe(true); - - expect(user.getSession().user).toBe('test'); - expect(user.getSession().sessionToken).toBe('mockSessionToken'); - }, - (error) => {}, - () => { - completed = true; - }, - ); - - backend.testLogin(); - http.verify(); - expect(user.getSession()).toEqual({ - user: 'test', - sessionToken: 'mockSessionToken', - staySignedIn: true, - isExternallyConnected: false, - }); - expect(completed).toBeTruthy(); -} - -describe('Service: Project Service', () => { - describe('Plot tests', () => { - configureWaveTesting( - fakeAsync(() => { - TestBed.configureTestingModule(module); - this.service = TestBed.inject(ProjectService); - this.http = TestBed.inject(HttpTestingController); // Mapping Query Service requires http for plot subscriptions - this.backend = new MockBackend(this.http, MockConfig.MOCK_URL); - this.service.setProject(this.service.createDefaultProject()); - - login(this.http, this.backend); - - // add a plot to the service. - - this.plot = Plot.fromDict({ - name: 'test_plot', - operator: { - id: 0, - operatorType: { - operatorType: 'r_script', - resultType: 'plot', - code: 'test_code', - } as RScriptTypeDict, - resultType: 'plot', - projection: 'EPSG:3857', - attributes: [], - dataTypes: [], - units: [], - rasterSources: [], - pointSources: [], - lineSources: [], - polygonSources: [], - operatorTypeParameterOptions: undefined, - }, - }); - this.plotUrl = - MockConfig.MOCK_URL + - '?time=2000-01-01T00:00:00.000Z&service=plot&request=&sessiontoken=mockSessionToken&crs=EPSG:3857&bbox=0,0,0,' + - '0&query=%7B%22type%22%3A%22r_script%22%2C%22params%22%3A%7B%22source%22%3A%22test_code%22%2C%22result%22%3A%' + - '22plot%22%2C%22plot_width%22%3A168%2C%22plot_height%22%3A168%7D%7D'; - this.completed = false; - - this.service.addPlot(this.plot).subscribe( - () => {}, - (error) => {}, - () => { - this.completed = true; - }, - ); - - // Wait until all promises are resolved (chain of multiple function calls in addPlot) - tick(); - - const request = this.http.expectOne(this.plotUrl); - request.flush({type: 'png', data: 'dummy_data'}); - }), - ); - - it('uses the expected http calls', () => { - this.http.verify(); - }); - - it('finalizes addPlot-Observable', () => { - expect(this.completed).toBeTruthy(); - }); - - it('finalizes removePlot-Observable', async () => { - let completed = false; - await this.service.removePlot(this.plot).subscribe( - () => {}, - (error) => {}, - () => { - completed = true; - }, - ); - expect(completed).toBeTruthy(); - }); - - it('adds plot', async () => { - await this.service.getProjectStream().subscribe((project) => { - expect(project.plots.length).toBe(1); - }); - await this.service.getPlotDataStream(this.plot).subscribe((data) => { - expect(data.data).toEqual('dummy_data'); - }); - }); - - it('removes plot', async () => { - await this.service.removePlot(this.plot); - await this.service.getProjectStream().subscribe((project) => { - expect(project.plots.length).toBe(0); - }); - }); - - it('clears plots', async () => { - this.service.clearPlots(); - await this.service.getProjectStream().subscribe((project) => { - expect(project.plots.length).toBe(0); - }); - }); - }); - - describe('Layer tests', () => { - configureWaveTesting( - fakeAsync(() => { - TestBed.configureTestingModule(module); - this.service = TestBed.inject(ProjectService); - this.http = TestBed.inject(HttpTestingController); // Mapping Query Service requires http for plot subscriptions - this.backend = new MockBackend(this.http, MockConfig.MOCK_URL); - this.service.setProject(this.service.createDefaultProject()); - - login(this.http, this.backend); - - this.layer = Layer.fromDict({ - name: 'test_layer', - operator: { - id: 0, - operatorType: new RasterSourceType({ - channel: 0, - sourcename: 'source', - transform: false, - }).toDict(), - resultType: 'raster', - projection: 'EPSG:3857', - attributes: [], - dataTypes: [], - units: [], - rasterSources: [], - pointSources: [], - lineSources: [], - polygonSources: [], - operatorTypeParameterOptions: undefined, - }, - symbology: { - symbologyType: 'RASTER', - opacity: 0.5, - unit: { - measurement: 'row', - unit: 'unknown', - }, - } as RasterSymbologyDict, - expanded: true, - visible: true, - editSymbology: false, - type: 'raster', - }); - - this.completed = false; - - this.service.addLayer(this.layer).subscribe( - () => {}, - (error) => {}, - () => { - this.completed = true; - }, - ); - }), - ); - - it('finalizes addLayer-Observable', () => { - expect(this.completed).toBeTruthy(); - }); - - it('adds layer', async () => { - await this.service.getLayerStream().subscribe((arr) => expect(arr.length).toBe(1)); - }); - - it('removes layer and finalizes Observable', async () => { - let completed = false; - await this.service.removeLayer(this.layer).subscribe( - () => {}, - (error) => {}, - () => { - completed = true; - }, - ); - expect(completed).toBeTruthy(); - await this.service.getProjectStream().subscribe((project) => { - expect(project.layers.length).toBe(0); - }); - }); - - it('clears layers', async () => { - this.service.clearLayers(); - await this.service.getProjectStream().subscribe((project) => { - expect(project.layers.length).toBe(0); - }); - }); - }); -}); diff --git a/projects/wave-core/src/lib/project/project.service.ts b/projects/wave-core/src/lib/project/project.service.ts deleted file mode 100644 index ba79bbb4..00000000 --- a/projects/wave-core/src/lib/project/project.service.ts +++ /dev/null @@ -1,1157 +0,0 @@ -import { - combineLatest as observableCombineLatest, - Observable, - Observer, - of as observableOf, - ReplaySubject, - Subject, - Subscription, -} from 'rxjs'; - -import {catchError, debounceTime, distinctUntilChanged, first, map, switchMap, tap} from 'rxjs/operators'; -import {Injectable} from '@angular/core'; - -import {Projection, Projections} from '../operators/projection.model'; - -import {Project} from './project.model'; - -import {Time, TimePoint, TimeStepDuration} from '../time/time.model'; -import {Config} from '../config.service'; -import {Plot, PlotData} from '../plots/plot.model'; -import {LoadingState} from './loading-state.model'; -import {MappingQueryService} from '../queries/mapping-query.service'; -import {NotificationService} from '../notification.service'; -import {Layer, LayerChanges, LayerData, RasterData, RasterLayer, VectorData, VectorLayer} from '../layers/layer.model'; -import {AbstractRasterSymbology, AbstractSymbology, AbstractVectorSymbology, PointSymbology} from '../layers/symbology/symbology.model'; -import {Provenance} from '../provenance/provenance.model'; -import {MapService} from '../map/map.service'; -import {WFSOutputFormats} from '../queries/output-formats/wfs-output-format.model'; -import {ResultTypes} from '../operators/result-type.model'; -import {LayerService} from '../layers/layer.service'; -import {HttpErrorResponse} from '@angular/common/http'; -import {LayoutService} from '../layout.service'; -import {DeprecatedMappingColorizerDoNotUse} from '../colors/colorizer-data.model'; - -/*** - * The ProjectService is the main housekeeping component of WAVE. - * All layers, plots, and provenance are registered with the ProjectService. - */ -@Injectable() -export class ProjectService { - private project$ = new ReplaySubject(1); - - private layerData$: Map, ReplaySubject>>; - private layerDataState$: Map, ReplaySubject>; - private layerDataSubscriptions: Map, Subscription>; - private layerSymbologyData$: Map, ReplaySubject>; - private layerSymbologyDataState$: Map, ReplaySubject>; - private layerSymbologyDataSubscriptions: Map, Subscription>; - private layerProvenanceData$: Map, ReplaySubject>>; - private layerProvenanceDataState$: Map, ReplaySubject>; - private layerProvenanceDataSubscriptions: Map, Subscription>; - private layerCombinedState$: Map, Observable>; - private layerChanges$: Map, ReplaySubject>>; - - private newLayer$: Subject>; - - private plotData$: Map>; - private plotDataState$: Map>; - private plotSubscriptions: Map; - private newPlot$: Subject; - - constructor( - private config: Config, - private notificationService: NotificationService, - private mappingQueryService: MappingQueryService, - private mapService: MapService, - private layerService: LayerService, - private layoutService: LayoutService, - ) { - this.plotData$ = new Map(); - this.plotDataState$ = new Map(); - this.plotSubscriptions = new Map(); - this.newPlot$ = new Subject(); - - this.layerData$ = new Map(); - this.layerDataState$ = new Map(); - this.layerDataSubscriptions = new Map(); - this.layerSymbologyData$ = new Map(); - this.layerSymbologyDataState$ = new Map(); - this.layerSymbologyDataSubscriptions = new Map(); - this.layerProvenanceData$ = new Map(); - this.layerProvenanceDataState$ = new Map(); - this.layerProvenanceDataSubscriptions = new Map(); - this.layerCombinedState$ = new Map(); - this.newLayer$ = new Subject>(); - this.layerChanges$ = new Map(); - } - - /** - * Generate a default Project with values from the config file. - */ - createDefaultProject(): Project { - let timeStepDuration: TimeStepDuration; - switch (this.config.DEFAULTS.PROJECT.TIMESTEP) { - case '15 minutes': - timeStepDuration = {durationAmount: 15, durationUnit: 'minutes'}; - break; - case '1 hour': - timeStepDuration = {durationAmount: 1, durationUnit: 'hour'}; - break; - case '1 day': - timeStepDuration = {durationAmount: 1, durationUnit: 'day'}; - break; - case '1 month': - timeStepDuration = {durationAmount: 1, durationUnit: 'month'}; - break; - case '6 months': - timeStepDuration = {durationAmount: 6, durationUnit: 'months'}; - break; - case '1 year': - timeStepDuration = {durationAmount: 1, durationUnit: 'year'}; - break; - default: - timeStepDuration = {durationAmount: 1, durationUnit: 'month'}; - } - - return new Project({ - name: this.config.DEFAULTS.PROJECT.NAME, - projection: Projections.fromCode(this.config.DEFAULTS.PROJECT.PROJECTION), - time: new TimePoint(this.config.DEFAULTS.PROJECT.TIME), - timeStepDuration, - }); - } - - /** - * Get a stream of Projects. This way compments can react to new Projects. - */ - getProjectStream(): Observable { - return this.project$; - } - - /** - * Set a new Project. The ProjectService will clear all layer, plots, and provenance. - */ - setProject(project: Project) { - // console.log("`setProject`"); - - // clear layer data - this.layerData$.forEach((subject) => subject.complete()); - this.layerData$.clear(); - this.layerDataState$.forEach((subject) => subject.complete()); - this.layerDataState$.clear(); - this.layerDataSubscriptions.forEach((subscription) => subscription.unsubscribe()); - this.layerDataSubscriptions.clear(); - this.layerProvenanceData$.forEach((subject) => subject.complete()); - this.layerProvenanceData$.clear(); - this.layerProvenanceDataState$.forEach((subject) => subject.complete()); - this.layerProvenanceDataState$.clear(); - this.layerProvenanceDataSubscriptions.forEach((subscription) => subscription.unsubscribe()); - this.layerProvenanceDataSubscriptions.clear(); - this.layerSymbologyData$.forEach((subject) => subject.complete()); - this.layerSymbologyData$.clear(); - this.layerSymbologyDataState$.forEach((subject) => subject.complete()); - this.layerSymbologyDataState$.clear(); - this.layerSymbologyDataSubscriptions.forEach((subscription) => subscription.unsubscribe()); - this.layerSymbologyDataSubscriptions.clear(); - this.layerCombinedState$.clear(); - - // clears all layer changes subscriptions, but completes them first - this.layerChanges$.forEach((subject) => subject.complete()); - this.layerChanges$.clear(); - - // clear plot data - this.plotData$.forEach((subject) => subject.complete()); - this.plotData$.clear(); - this.plotDataState$.forEach((subject) => subject.complete()); - this.plotDataState$.clear(); - this.plotSubscriptions.forEach((subscription) => subscription.unsubscribe()); - this.plotSubscriptions.clear(); - - // add plot streams - for (const plot of project.plots) { - this.createPlotDataStreams(plot); - } - - // add layer streams - for (const layer of project.layers) { - this.createLayerDataStreams(layer); - this.createLayerChangesStream(layer); - } - - this.project$.next(project); - } - - /** - * Set the time of the current project. - */ - setTime(time: Time) { - this.project$.pipe(first()).subscribe((project) => { - const oldTime = project.time; - if (time && time.isValid() && !time.isSame(oldTime)) { - this.changeProjectConfig({ - time, - }); - } - }); - } - - /** - * Set a ttime duration for the current project. - */ - setTimeStepDuration(timeStepDuration: TimeStepDuration) { - this.changeProjectConfig({ - timeStepDuration, - }); - } - - /** - * Set the name of the current Project. - */ - setName(name: string) { - this.changeProjectConfig({name}); - } - - /** - * Set the projection used by the current project. - */ - setProjection(projection: Projection) { - this.changeProjectConfig({ - projection, - }); - } - - /** - * Get a stream of the projects projection. - */ - getProjectionStream(): Observable { - return this.project$.pipe( - map((project) => project.projection), - distinctUntilChanged(), - ); - } - - /** - * Get a stream of the projects time. - */ - getTimeStream(): Observable