Compare commits
280 Commits
747499d009
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b2ea10fdc | ||
| c20754e10a | |||
|
|
c4b8e9664c | ||
| 7822015f8c | |||
| 48261c9657 | |||
|
|
a6bd28ac45 | ||
|
|
674a0f2a9e | ||
| 77800fe0f7 | |||
| 3251ba4022 | |||
| a758a38a0a | |||
| 3c6a8e28c1 | |||
| b72e309fbe | |||
| d7b978c477 | |||
| 930d4fe0b7 | |||
| 642ea33c3c | |||
| 429ab24408 | |||
|
|
eed70c449b | ||
| 4bef16aa2b | |||
| 05bc18c291 | |||
| 35ab2f7c90 | |||
| 2eca9b2562 | |||
|
|
e0c89f4358 | ||
| 604c1176c3 | |||
|
|
0ff8992874 | ||
| b5b84c2547 | |||
| c2b016b2b9 | |||
|
|
d44531274b | ||
| c52ee36d1b | |||
|
|
9b86927e2c | ||
|
|
e224b80995 | ||
|
|
88f3d9ef1a | ||
| 6737029a61 | |||
|
|
d4786564bd | ||
| 6fd69d7999 | |||
|
|
4ec75b3d5a | ||
| 04e3f1e71f | |||
| f66187d3a2 | |||
|
|
df77631299 | ||
| a8d0f05c81 | |||
|
|
df0d13e5dd | ||
|
|
c79637be77 | ||
|
|
b347220dd4 | ||
|
|
b5e11da9a8 | ||
|
|
edeadef96f | ||
|
|
267a299589 | ||
|
|
9d45c25a95 | ||
|
|
2ffce50c47 | ||
|
|
f50ff878e0 | ||
| 09c74448a8 | |||
| 205b73b30e | |||
|
|
313cc59fe7 | ||
| c3fb42c65f | |||
|
|
6b73fb0d55 | ||
| ea641caf38 | |||
| ac15b2018d | |||
|
|
fe73f615ad | ||
|
|
3e1b3ee78e | ||
|
|
58391b7828 | ||
|
|
b2b2a1e8be | ||
|
|
0d96a1be4f | ||
| d599430cb0 | |||
|
|
e17911b339 | ||
|
|
9d6cbffb3d | ||
|
|
a11eb81e73 | ||
|
|
4fc3ad933c | ||
|
|
e6d90c9e61 | ||
| 250b3841fe | |||
| 51291cd86f | |||
|
|
e9e3b719a4 | ||
|
|
1c0ad57b0a | ||
|
|
8684ba25c8 | ||
| 78ca3044cf | |||
| 2e55b5a70e | |||
|
|
af0a3dca2d | ||
| f039898c26 | |||
|
|
ab19b1c2ce | ||
| a2641f8ea5 | |||
|
|
d6841c8f83 | ||
| 187b24ab97 | |||
| b80ddf7854 | |||
|
|
79bc3d9082 | ||
| 1c92ad4c28 | |||
|
|
61e6de0052 | ||
| fb25b92349 | |||
|
|
e78f2893ae | ||
| 51170b45e9 | |||
|
|
7365bea145 | ||
| dc096065b4 | |||
|
|
b9850311ea | ||
| ee9c050db3 | |||
|
|
95200d9920 | ||
|
|
ee1ce21cca | ||
|
|
467f7447bf | ||
|
|
1df4496058 | ||
|
|
134220d75f | ||
|
|
80ef4ed6fe | ||
|
|
2137f3f07e | ||
| a46e8040b2 | |||
|
|
2ca9730735 | ||
| 3d2ca8fb9f | |||
| 6810da8b79 | |||
|
|
4866a6f22d | ||
| 84a1004977 | |||
| 39c619a837 | |||
|
|
758613aa12 | ||
| 6914a61bc4 | |||
| 9f43287433 | |||
|
|
10df983ae3 | ||
| 78249811ab | |||
| df14427d60 | |||
|
|
c7c131d437 | ||
| b2fe8f3bd7 | |||
|
|
3027c69fa8 | ||
| 5995d205a4 | |||
|
|
fd479c92d8 | ||
| e9880d6eb2 | |||
|
|
a4438d8a90 | ||
| 89061774de | |||
|
|
362e6c8534 | ||
| 64a0e58238 | |||
|
|
a3d4dfbd59 | ||
| 4c106ebff3 | |||
|
|
d21f304081 | ||
| 2bad3274fd | |||
|
|
5c8fd64521 | ||
| 72ba8eca81 | |||
|
|
f89f741265 | ||
| 50af55acb2 | |||
|
|
cc879b85e5 | ||
| b4a0a4584d | |||
| 8ab1611f39 | |||
|
|
475c522039 | ||
| 068396ac9a | |||
|
|
4a30707ec6 | ||
| 852b1db895 | |||
|
|
fcbd68eca0 | ||
| 3a42f9114e | |||
| 3f664b472c | |||
|
|
57811f3f2e | ||
| 5e1bc6d705 | |||
| d4a230f96d | |||
|
|
ed1e1478b2 | ||
| afe013a59a | |||
| db3734f8a3 | |||
|
|
86f75c7f78 | ||
| a7abb4072b | |||
|
|
61d6446d75 | ||
| 392008ae4b | |||
| 093c26c7f3 | |||
|
|
a8e1ba6c02 | ||
| e64fbfd014 | |||
| 8cd7b85de2 | |||
|
|
ddc7f97e27 | ||
| 24e3765c28 | |||
|
|
86f3ddb34b | ||
| d6c55ef82b | |||
| d977ddfb7b | |||
|
|
0e8bd5343d | ||
| ceeaa89ba3 | |||
|
|
c3dbf85eb6 | ||
| ad5fe95b55 | |||
|
|
31d3e58062 | ||
| 0231421cef | |||
|
|
6b95fb7f77 | ||
| da7e193219 | |||
| 31f9b48bd7 | |||
|
|
1d6b30edff | ||
| 349a76395b | |||
|
|
32b3b98f76 | ||
| 010ed6e010 | |||
| a8675f5c49 | |||
|
|
f76ef44dee | ||
| 2387a0e39e | |||
| 98980fc857 | |||
|
|
6f7d8fe248 | ||
| 03a1ccd597 | |||
|
|
f2c133e9bd | ||
|
|
9c866e500f | ||
| 3b692359c6 | |||
| 3d4042e8c6 | |||
|
|
3db760dd96 | ||
| b5828cd0fa | |||
| af4e6f45d1 | |||
|
|
79def90bc7 | ||
| 53c60427f1 | |||
|
|
7d7e5bcd37 | ||
| 72a172ccb2 | |||
| 2728a91ab4 | |||
|
|
28d2b5d4a3 | ||
| b70e385097 | |||
| 7392c6170c | |||
| 367348088a | |||
|
|
5efd5b78c9 | ||
| 0498d64c36 | |||
|
|
e17ac435b5 | ||
|
|
3e11c7cefd | ||
|
|
b3dcd1e58b | ||
|
|
681fc819a6 | ||
| 2a62d2df48 | |||
|
|
004bcea0b6 | ||
| 8efa46fa66 | |||
| cefa788295 | |||
| 2da783d6be | |||
| 749be159f1 | |||
|
|
4e24527950 | ||
| 45263a59f4 | |||
|
|
5cdef30c71 | ||
| cdba2af921 | |||
| 658c2c84cd | |||
| 3f9b4dcdaa | |||
|
|
a63159367f | ||
| b9d1c8f61f | |||
|
|
eb34de193c | ||
| 5612bb3d66 | |||
| 0e42efac75 | |||
| 3247880b7c | |||
| a250ecdcc1 | |||
| 93e497ec3f | |||
| 10a1f07622 | |||
| 07d6c1bc10 | |||
|
|
1bddc28767 | ||
| a999c05631 | |||
|
|
f3252a378d | ||
| 4ab1e43d40 | |||
|
|
2719f2fcf4 | ||
| 55914bf7d2 | |||
| 26ca9be4e7 | |||
| 0ed342404e | |||
|
|
26ae1c7f06 | ||
| f71d0fe256 | |||
|
|
7544203202 | ||
| 41a30e0b64 | |||
| f14fc1a4fc | |||
|
|
21ebda4753 | ||
| 3a80a6f7f3 | |||
| 71a2ef44e6 | |||
|
|
1610391d56 | ||
| b778e5726c | |||
| fc4abf9a5b | |||
|
|
1274d96f1d | ||
| 35ccb4f4c5 | |||
|
|
d6587bd63b | ||
|
|
ede75f63f5 | ||
| 274f33e709 | |||
| 4384b12944 | |||
|
|
10ebdf276a | ||
| 9c270bfe75 | |||
| 9031d3e171 | |||
|
|
c3158c1064 | ||
| 315b64a561 | |||
|
|
030dbcec5d | ||
| 876020828e | |||
| 393b881e3b | |||
| 8594a94d62 | |||
|
|
c543ac7c94 | ||
| 97d6d569a0 | |||
| 023048a5bb | |||
| 4a685d675d | |||
|
|
1125f4586e | ||
| 3bdba527ec | |||
| fb03cfce44 | |||
| 6f93cf254c | |||
| b5a3a62cee | |||
| d306d5c4c1 | |||
| e79ae2f623 | |||
| bdf4e03b49 | |||
| 7d5c10d902 | |||
| fb192c6e4d | |||
|
|
6356f149a6 | ||
| 5c5914327c | |||
|
|
e306bf601f | ||
| f8459aaca4 | |||
|
|
47fbc5eab9 | ||
| 564d08b5b9 | |||
| 7e17a49dc6 | |||
|
|
ce52cbdbed | ||
| 752e1e2c42 | |||
|
|
6b617ed4ad | ||
| 9b19950945 | |||
|
|
3f286ee042 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -51,5 +51,5 @@ projects/common-map/node_modules/
|
||||
.angular/*
|
||||
projects/common-map3d/node_modules/
|
||||
projects/common-map/node_modules/
|
||||
projects/ngx-openlayers/node_modules/
|
||||
projects/ng-openlayers/node_modules/
|
||||
projects/common/node_modules/
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
This is a sample FarmMaps client in Angular 7.x.
|
||||
|
||||
|
||||
## Quick start
|
||||
|
||||
Use one of the two options below to get started.
|
||||
|
||||
111
angular.json
111
angular.json
@@ -129,43 +129,14 @@
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "farmmaps-lib-app:build"
|
||||
"buildTarget": "farmmaps-lib-app:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"builder": "@angular/build:unit-test",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"karmaConfig": "src/karma.conf.js",
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"farmmaps-lib-app-e2e": {
|
||||
"root": "e2e/",
|
||||
"projectType": "application",
|
||||
"prefix": "",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "e2e/protractor.conf.js",
|
||||
"devServerTarget": "farmmaps-lib-app:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "farmmaps-lib-app:serve:production"
|
||||
}
|
||||
"browsers": ["chromium"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,11 +160,10 @@
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"builder": "@angular/build:unit-test",
|
||||
"options": {
|
||||
"main": "projects/common/src/test.ts",
|
||||
"tsConfig": "projects/common/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/common/karma.conf.js"
|
||||
"browsers": ["chromium"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,19 +179,18 @@
|
||||
"options": {
|
||||
"tsConfig": "projects/common-map/tsconfig.lib.json",
|
||||
"project": "projects/common-map/ng-package.json"
|
||||
}
|
||||
, "configurations": {
|
||||
"production": {
|
||||
"tsConfig": "projects/common-map/tsconfig.lib.prod.json"
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "projects/common-map/tsconfig.lib.prod.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"builder": "@angular/build:unit-test",
|
||||
"options": {
|
||||
"main": "projects/common-map/src/test.ts",
|
||||
"tsConfig": "projects/common-map/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/common-map/karma.conf.js"
|
||||
"browsers": ["chromium"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,47 +214,45 @@
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"builder": "@angular/build:unit-test",
|
||||
"options": {
|
||||
"main": "projects/common-map3d/src/test.ts",
|
||||
"tsConfig": "projects/common-map3d/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/common-map3d/karma.conf.js"
|
||||
"browsers": ["chromium"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ngx-openlayers": {
|
||||
"ng-openlayers": {
|
||||
"projectType": "library",
|
||||
"root": "projects/ngx-openlayers",
|
||||
"sourceRoot": "projects/ngx-openlayers/src",
|
||||
"prefix": "lib",
|
||||
"root": "projects/ng-openlayers",
|
||||
"sourceRoot": "projects/ng-openlayers/src",
|
||||
"prefix": "ng-openlayers",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"options": {
|
||||
"tsConfig": "projects/ngx-openlayers/tsconfig.lib.json",
|
||||
"project": "projects/ngx-openlayers/ng-package.json"
|
||||
"tsConfig": "projects/ng-openlayers/tsconfig.lib.json",
|
||||
"project": "projects/ng-openlayers/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "projects/ngx-openlayers/tsconfig.lib.prod.json"
|
||||
"tsConfig": "projects/ng-openlayers/tsconfig.lib.prod.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"builder": "@angular/build:unit-test",
|
||||
"options": {
|
||||
"main": "projects/ngx-openlayers/src/test.ts",
|
||||
"tsConfig": "projects/ngx-openlayers/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/ngx-openlayers/karma.conf.js"
|
||||
"tsConfig": "projects/ng-openlayers/tsconfig.spec.json",
|
||||
"browsers": ["chromium"]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-eslint/builder:lint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"projects/ngx-openlayers/**/*.ts",
|
||||
"projects/ngx-openlayers/**/*.html"
|
||||
"projects/ng-openlayers/**/*.ts",
|
||||
"projects/ng-openlayers/**/*.html"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -294,5 +261,31 @@
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
},
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"type": "component"
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"type": "directive"
|
||||
},
|
||||
"@schematics/angular:service": {
|
||||
"type": "service"
|
||||
},
|
||||
"@schematics/angular:guard": {
|
||||
"typeSeparator": "."
|
||||
},
|
||||
"@schematics/angular:interceptor": {
|
||||
"typeSeparator": "."
|
||||
},
|
||||
"@schematics/angular:module": {
|
||||
"typeSeparator": "."
|
||||
},
|
||||
"@schematics/angular:pipe": {
|
||||
"typeSeparator": "."
|
||||
},
|
||||
"@schematics/angular:resolver": {
|
||||
"typeSeparator": "."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
|
||||
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.e2e.json')
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
}
|
||||
};
|
||||
@@ -1,23 +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('Welcome to farmmaps-lib-app!');
|
||||
});
|
||||
|
||||
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));
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class AppPage {
|
||||
navigateTo() {
|
||||
return browser.get(browser.baseUrl) as Promise<any>;
|
||||
}
|
||||
|
||||
getTitleText() {
|
||||
return element(by.css('app-root h1')).getText() as Promise<string>;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/app",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
||||
41164
package-lock.json
generated
41164
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
125
package.json
125
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "farmmaps-lib-app",
|
||||
"version": "4.3.0",
|
||||
"scripts": {
|
||||
"version": "4.20.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
@@ -10,41 +10,41 @@
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^16.2.12",
|
||||
"@angular/common": "^16.2.12",
|
||||
"@angular/compiler": "^16.2.12",
|
||||
"@angular/core": "^16.2.12",
|
||||
"@angular-eslint/eslint-plugin": "^15.2.1",
|
||||
"@angular/forms": "^16.2.12",
|
||||
"@angular/platform-browser": "^16.2.12",
|
||||
"@angular/platform-browser-dynamic": "^16.2.12",
|
||||
"@angular/router": "^16.2.12",
|
||||
"dependencies": {
|
||||
"@angular-eslint/eslint-plugin": "20.7.0",
|
||||
"@angular/animations": "21.1.0",
|
||||
"@angular/common": "21.1.0",
|
||||
"@angular/compiler": "21.1.0",
|
||||
"@angular/core": "21.1.0",
|
||||
"@angular/forms": "21.1.0",
|
||||
"@angular/platform-browser": "21.1.0",
|
||||
"@angular/platform-browser-dynamic": "21.1.0",
|
||||
"@angular/router": "21.1.0",
|
||||
"@farmmaps/common": "file:dist/common",
|
||||
"@farmmaps/common-map": "file:dist/common-map",
|
||||
"@farmmaps/common-map3d": "file:dist/common-map3d",
|
||||
"ngx-openlayers": "file:dist/ngx-openlayers",
|
||||
"@microsoft/signalr": "^3.1.16",
|
||||
"@ng-bootstrap/ng-bootstrap": "^15.0.0",
|
||||
"@ngrx/effects": "^16",
|
||||
"@ngrx/router-store": "^16",
|
||||
"@ngrx/store": "^16",
|
||||
"@popperjs/core": "^2.11.6",
|
||||
"angular-oauth2-oidc": "^13",
|
||||
"assert": "^2.0.0",
|
||||
"bootstrap": "^5.2.0",
|
||||
"@farmmaps/ng-openlayers": "file:dist/ng-openlayers",
|
||||
"@microsoft/signalr": "10.0.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "20.0.0",
|
||||
"@ngrx/effects": "21.0.1",
|
||||
"@ngrx/router-store": "21.0.1",
|
||||
"@ngrx/store": "21.0.1",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"angular-oauth2-oidc": "20.0.2",
|
||||
"assert": "2.1.0",
|
||||
"bootstrap": "5.3.8",
|
||||
"browserify-zlib": "^0.2.0",
|
||||
"buffer": "^6.0.3",
|
||||
"cesium": "^1.97.0",
|
||||
"core-js": "^2.6.12",
|
||||
"https-browserify": "^1.0.0",
|
||||
"moment": "^2.29.4",
|
||||
"ngrx-store-localstorage": "16.0.0",
|
||||
"ngx-avatars": "1.5.0",
|
||||
"ngx-clipboard": "^15.1.0",
|
||||
"ngx-image-cropper": "^7.2.1",
|
||||
"ngx-uploadx": "^5.2.0",
|
||||
"ol": "~6.3.1",
|
||||
"ngrx-store-localstorage": "20.1.0",
|
||||
"ngx-avatars": "1.10.1",
|
||||
"ngx-clipboard": "^16.0.0",
|
||||
"ngx-image-cropper": "^7.0.0",
|
||||
"ngx-uploadx": "7.0.1",
|
||||
"ol": "^8.2.0",
|
||||
"olcs": "^2.13.1",
|
||||
"resumablejs": "^1.1.0",
|
||||
"rxjs": "^7.8.1",
|
||||
@@ -54,36 +54,47 @@
|
||||
"tslib": "^2.4.0",
|
||||
"url": "^0.11.0",
|
||||
"util": "^0.12.4",
|
||||
"zone.js": "~0.13.3"
|
||||
"zone.js": "~0.15.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-builders/custom-webpack": "^16",
|
||||
"@angular-devkit/build-angular": "^16.2.11",
|
||||
"@angular/cli": "^16.2.11",
|
||||
"@angular/compiler-cli": "^16.2.12",
|
||||
"@angular/language-service": "^16.2.12",
|
||||
"@angular/localize": "^16.2.12",
|
||||
"optionalDependencies": {
|
||||
"@lmdb/lmdb-linux-x64": "^3.1.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "^4.21.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-builders/custom-webpack": "21.0.3",
|
||||
"@angular-devkit/build-angular": "21.1.0",
|
||||
"@angular/build": "21.1.0",
|
||||
"@angular/cli": "21.1.0",
|
||||
"@angular/compiler-cli": "21.1.0",
|
||||
"@angular/language-service": "21.1.0",
|
||||
"@angular/localize": "21.1.0",
|
||||
"@types/arcgis-rest-api": "^10.4.5",
|
||||
"@types/jasmine": "~2.8.8",
|
||||
"@types/jasminewd2": "^2.0.9",
|
||||
"@types/node": "^12.20.15",
|
||||
"@typescript-eslint/eslint-plugin": "^6.18.0",
|
||||
"@typescript-eslint/eslint-plugin-tslint": "^6.18.0",
|
||||
"@typescript-eslint/parser": "^6.18.0",
|
||||
"codelyzer": "^0.0.28",
|
||||
"eslint": "^8.35.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"jasmine-core": "^4.3.0",
|
||||
"jasmine-spec-reporter": "^7.0.0",
|
||||
"karma": "^6.3.20",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage-istanbul-reporter": "^3.0.3",
|
||||
"karma-jasmine": "^5.1.0",
|
||||
"karma-jasmine-html-reporter": "^2.0.0",
|
||||
"ng-packagr": "^16.2.3",
|
||||
"protractor": "~7.0.0",
|
||||
"@types/node": "^22.5.4",
|
||||
"@typescript-eslint/eslint-plugin": "8.53.1",
|
||||
"@typescript-eslint/parser": "8.53.1",
|
||||
"@vitest/browser": "4.0.17",
|
||||
"@vitest/browser-playwright": "^4.0.17",
|
||||
"eslint": "9.39.2",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"eslint-plugin-import": "2.32.0",
|
||||
"jsdom": "^27.4.0",
|
||||
"ng-packagr": "21.1.0",
|
||||
"ts-node": "^8.8.1",
|
||||
"typescript": "~4.9.3"
|
||||
"typescript": "~5.9.3",
|
||||
"vitest": "4.0.17"
|
||||
},
|
||||
"overrides": {
|
||||
"ngrx-store-localstorage": {
|
||||
"@angular/common": "$@angular/common",
|
||||
"@angular/core": "$@angular/core"
|
||||
},
|
||||
"ngx-avatars": {
|
||||
"@angular/common": "$@angular/common",
|
||||
"@angular/core": "$@angular/core"
|
||||
},
|
||||
"ngx-uploadx": {
|
||||
"@angular/common": "$@angular/common",
|
||||
"@angular/core": "$@angular/core"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
207
projects/common-map/package-lock.json
generated
207
projects/common-map/package-lock.json
generated
@@ -11,20 +11,205 @@
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^16.2.12",
|
||||
"@ngrx/effects": "^16",
|
||||
"@ngrx/router-store": "^16",
|
||||
"@ngrx/store": "^16",
|
||||
"ngrx-store-localstorage": "16.0.0",
|
||||
"ngx-openlayers": "file:dist/ngx-openlayers",
|
||||
"ol": ">=6.8.1",
|
||||
"tassign": ">1.0.0"
|
||||
"@angular/core": "20.3.16",
|
||||
"@ngrx/effects": "20.1.0",
|
||||
"@ngrx/router-store": "20.1.0",
|
||||
"@ngrx/store": "20.1.0",
|
||||
"ngrx-store-localstorage": "20.1.0",
|
||||
"tassign": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"../../dist/libs/ng-openlayers": {
|
||||
"version": "18.0.0",
|
||||
"extraneous": true,
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^18.2.3",
|
||||
"@angular/core": "^18.2.3",
|
||||
"ol": "^8.2.0"
|
||||
}
|
||||
},
|
||||
"dist/ng-openlayers": {
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/@angular/common": {
|
||||
"version": "20.3.16",
|
||||
"resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.16.tgz",
|
||||
"integrity": "sha512-GRAziNlntwdnJy3F+8zCOvDdy7id0gITjDnM6P9+n2lXvtDuBLGJKU3DWBbvxcCjtD6JK/g/rEX5fbCxbUHkQQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "20.3.16",
|
||||
"rxjs": "^6.5.3 || ^7.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/core": {
|
||||
"version": "20.3.16",
|
||||
"resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.16.tgz",
|
||||
"integrity": "sha512-KSFPKvOmWWLCJBbEO+CuRUXfecX2FRuO0jNi9c54ptXMOPHlK1lIojUnyXmMNzjdHgRug8ci9qDuftvC2B7MKg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/compiler": "20.3.16",
|
||||
"rxjs": "^6.5.3 || ^7.4.0",
|
||||
"zone.js": "~0.15.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@angular/compiler": {
|
||||
"optional": true
|
||||
},
|
||||
"zone.js": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/platform-browser": {
|
||||
"version": "20.3.16",
|
||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.16.tgz",
|
||||
"integrity": "sha512-YsrLS6vyS77i4pVHg4gdSBW74qvzHjpQRTVQ5Lv/OxIjJdYYYkMmjNalCNgy1ZuyY6CaLIB11ccxhrNnxfKGOQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/animations": "20.3.16",
|
||||
"@angular/common": "20.3.16",
|
||||
"@angular/core": "20.3.16"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@angular/animations": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/router": {
|
||||
"version": "20.3.16",
|
||||
"resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.16.tgz",
|
||||
"integrity": "sha512-e1LiQFZaajKqc00cY5FboIrWJZSMnZ64GDp5R0UejritYrqorQQQNOqP1W85BMuY2owibMmxVfX+dJg/Mc8PuQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "20.3.16",
|
||||
"@angular/core": "20.3.16",
|
||||
"@angular/platform-browser": "20.3.16",
|
||||
"rxjs": "^6.5.3 || ^7.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrx/effects": {
|
||||
"version": "20.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-20.1.0.tgz",
|
||||
"integrity": "sha512-wkIu0QnTarBd1zUswk643H5SILO9Be1OeswMe7g4tXlkNLFRPkyu0BUzXT80PsUPP5p0VrdFz3akrn3HHjjTjA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^20.0.0",
|
||||
"@ngrx/store": "20.1.0",
|
||||
"rxjs": "^6.5.3 || ^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrx/router-store": {
|
||||
"version": "20.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-20.1.0.tgz",
|
||||
"integrity": "sha512-XlpQsgmEc1E9Ogiv6QbJ8g8JzjrJOlr7JX9FngHIDLyXQFCMn5wcXsqhjiBjG9JgJLwlzV+v14i7EM/nqwQCGA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^20.0.0",
|
||||
"@angular/core": "^20.0.0",
|
||||
"@angular/router": "^20.0.0",
|
||||
"@ngrx/store": "20.1.0",
|
||||
"rxjs": "^6.5.3 || ^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrx/store": {
|
||||
"version": "20.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@ngrx/store/-/store-20.1.0.tgz",
|
||||
"integrity": "sha512-o8j3CGAGedm+BIb+QDhNXrVaU//n9uF0wH0HZWtXHmW1mjRBaQiUA+ZPMUkDwAeN8KuOcoIEC+2QUXxXGVI7ow==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^20.0.0",
|
||||
"rxjs": "^6.5.3 || ^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ngrx-store-localstorage": {
|
||||
"version": "20.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ngrx-store-localstorage/-/ngrx-store-localstorage-20.1.0.tgz",
|
||||
"integrity": "sha512-/5+i5qTxZdE8Q5qdSmj7+9JvriAnHwW7RsXzh1rrQ/UHA9vf12q6mJ6wYTTehUO4Qcl2t/K5MRkooN2eG2ZEvw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"deepmerge": "^4.2.2",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=20.0.0",
|
||||
"@angular/core": ">=20.0.0",
|
||||
"@ngrx/store": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
|
||||
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tassign": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tassign/-/tassign-1.0.0.tgz",
|
||||
"integrity": "sha512-k0Ti9f+A1R0BRdArEbiUHldd+A40kZ5qsiNSNk4czx61wkAoSZYjqkaQs0jC63AfgPdCXVPstDq2ZW5ZLRTCgw==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz",
|
||||
"integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ=="
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
|
||||
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,16 @@
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^16.2.12",
|
||||
"ngrx-store-localstorage": "16.0.0",
|
||||
"@ngrx/effects": "^16",
|
||||
"@ngrx/router-store": "^16",
|
||||
"@ngrx/store": "^16",
|
||||
"tassign": ">1.0.0",
|
||||
"ngx-openlayers": "file:dist/ngx-openlayers",
|
||||
"ol": ">=6.8.1"
|
||||
"@angular/core": "21.1.0",
|
||||
"ngrx-store-localstorage": "20.1.0",
|
||||
"@ngrx/effects": "21.0.1",
|
||||
"@ngrx/router-store": "21.0.1",
|
||||
"@ngrx/store": "21.0.1",
|
||||
"tassign": "^1.0.0"
|
||||
},
|
||||
"overrides": {
|
||||
"ngrx-store-localstorage": {
|
||||
"@angular/core": "$@angular/core"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@ export const TOGGLESHOWDATALAYERSLIDE = '[Map] ToggleShowDataLayerSlide'
|
||||
export const SETVIEWSTATE = '[Map] SetViewState'
|
||||
export const CLEARFEATURES = '[Map] ClearFeatures';
|
||||
export const SETPANELEXTRAWIDE = '[Map] SetPanelExtraWide';
|
||||
export const BACKUPFEATURES = '[Map] BackupFeatures';
|
||||
export const RESTOREFEATURES = '[Map] RestoreFeatures';
|
||||
|
||||
export class Clear implements Action {
|
||||
readonly type = CLEAR;
|
||||
@@ -300,7 +302,7 @@ export class SetReplaceUrl implements Action {
|
||||
export class SetFeatures implements Action {
|
||||
readonly type = SETFEATURES;
|
||||
|
||||
constructor(public features: Array<Feature<Geometry>>) { }
|
||||
constructor(public features: Array<Feature<Geometry>>, public zoomToExtent: boolean = true) { }
|
||||
}
|
||||
|
||||
export class SetLayerValuesLocation implements Action {
|
||||
@@ -347,6 +349,16 @@ export class SetPanelExtraWide implements Action {
|
||||
constructor(public panelExtraWide:boolean) {}
|
||||
}
|
||||
|
||||
export class BackupFeatures implements Action {
|
||||
readonly type = BACKUPFEATURES;
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
export class RestoreFeatures implements Action {
|
||||
readonly type = RESTOREFEATURES;
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
export type Actions = SetMapState
|
||||
| Init
|
||||
| Clear
|
||||
@@ -395,5 +407,7 @@ export type Actions = SetMapState
|
||||
| ToggleShowDataLayerSlide
|
||||
| SetViewState
|
||||
| ClearFeatures
|
||||
| SetPanelExtraWide;
|
||||
| SetPanelExtraWide
|
||||
| BackupFeatures
|
||||
| RestoreFeatures;
|
||||
|
||||
|
||||
@@ -1,78 +1,79 @@
|
||||
import { NgModule ,ModuleWithProviders} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
//external modules
|
||||
import { AngularOpenlayersModule } from 'ngx-openlayers';
|
||||
import { StoreModule, ActionReducer, MetaReducer } from '@ngrx/store';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import { ActionReducer, MetaReducer, StoreModule } from '@ngrx/store';
|
||||
import { AngularOpenlayersModule } from '@farmmaps/ng-openlayers';
|
||||
|
||||
//common modules
|
||||
import { AppCommonModule } from '@farmmaps/common';
|
||||
|
||||
import { MODULE_NAME } from './module-name';
|
||||
import * as mapReducers from './reducers/map.reducer';
|
||||
import * as mapActions from './actions/map.actions';
|
||||
import * as mapEffects from './effects/map.effects';
|
||||
import { MODULE_NAME } from './module-name';
|
||||
import * as mapReducers from './reducers/map.reducer';
|
||||
|
||||
import { IMapState} from './models/map.state';
|
||||
import { ISelectedFeatures } from './models/selected.features';
|
||||
import { IItemLayer,ItemLayer,ITemporalItemLayer,TemporalItemLayer } from './models/item.layer';
|
||||
import { IClickedFeature } from './models/clicked.feature';
|
||||
import { IItemLayer, ItemLayer, ITemporalItemLayer, TemporalItemLayer } from './models/item.layer';
|
||||
import { IMapState } from './models/map.state';
|
||||
import { IPeriodState } from './models/period.state';
|
||||
import { ISelectedFeatures } from './models/selected.features';
|
||||
|
||||
// components
|
||||
import { GpsLocation} from './components/aol/gps-location/gps-location.component';
|
||||
import {FeatureListFeatureCropfieldComponent } from './components/feature-list-feature-cropfield/feature-list-feature-cropfield.component';
|
||||
import { FeatureListFeatureCroppingschemeComponent} from './components/feature-list-feature-croppingscheme/feature-list-feature-croppingscheme.component';
|
||||
import { ItemWidgetListComponent} from './components/item-widget-list/item-widget-list.component';
|
||||
import { AbstractItemListItemComponent, ItemListItemComponent, AbstractItemWidgetComponent } from './components/item-list-item/item-list-item.component';
|
||||
import { ItemListItemContainerComponent } from './components/item-list-item-container/item-list-item-container.component';
|
||||
import { AbstractItemListComponent,ItemListComponent} from './components/item-list/item-list.component';
|
||||
import { AbstractSelectedItemComponent, SelectedItemComponent } from './components/selected-item/selected-item.component';
|
||||
import { SelectedItemCropfieldComponent } from './components/selected-item-cropfield/selected-item-cropfield.component';
|
||||
import { SelectedItemGeotiffComponent } from './components/selected-item-geotiff/selected-item-geotiff.component';
|
||||
import { SelectedItemTemporalComponent} from './components/selected-item-temporal/selected-item-temporal.component';
|
||||
import {SelectedItemShapeComponent } from './components/selected-item-shape/selected-item-shape.component';
|
||||
import { SelectedItemContainerComponent } from './components/selected-item-container/selected-item-container.component';
|
||||
import { AbstractFeatureListFeatureComponent, FeatureListFeatureComponent } from './components/feature-list-feature/feature-list-feature.component';
|
||||
import {FeatureListFeatureContainerComponent } from './components/feature-list-feature-container/feature-list-feature-container.component';
|
||||
import { FeatureListCroppingschemeComponent } from './components/feature-list-croppingscheme/feature-list-croppingscheme.component';
|
||||
import {FeatureListCropfieldComponent } from './components/feature-list-cropfield/feature-list-cropfield.component';
|
||||
import {FeatureListContainerComponent } from './components/feature-list-container/feature-list-container.component';
|
||||
import { WidgetHostDirective} from './components/widget-host/widget-host.directive';
|
||||
import { FeatureListComponent,AbstractFeatureListComponent} from './components/feature-list/feature-list.component';
|
||||
import { MapRoutingModule } from './common-map-routing.module';
|
||||
import { FileDropTargetComponent } from './components/aol/file-drop-target/file-drop-target.component';
|
||||
import { ItemVectorSourceComponent } from './components/aol/item-vector-source/item-vector-source.component';
|
||||
import { GpsLocation } from './components/aol/gps-location/gps-location.component';
|
||||
import { ItemLayersComponent } from './components/aol/item-layers/item-layers.component';
|
||||
import { ZoomToExtentComponent } from './components/aol/zoom-to-extent/zoom-to-extent.component';
|
||||
import { RotationResetComponent } from './components/aol/rotation-reset/rotation-reset.component';
|
||||
import { ItemVectorSourceComponent } from './components/aol/item-vector-source/item-vector-source.component';
|
||||
import { LayerListComponent } from './components/aol/layer-list/layer-list.component';
|
||||
import { LayerValuesComponent } from './components/aol/layer-values/layer-values.component';
|
||||
import { LayerVectorImageComponent } from './components/aol/layer-vector-image/layer-vector-image.component';
|
||||
import { PanToLocation } from './components/aol/pan-to-location/pan-to-location.component';
|
||||
import { RotationResetComponent } from './components/aol/rotation-reset/rotation-reset.component';
|
||||
import { ZoomToExtentComponent } from './components/aol/zoom-to-extent/zoom-to-extent.component';
|
||||
import { FeatureListContainerComponent } from './components/feature-list-container/feature-list-container.component';
|
||||
import { FeatureListCropfieldComponent } from './components/feature-list-cropfield/feature-list-cropfield.component';
|
||||
import { FeatureListObservationComponent } from './components/feature-list-observation/feature-list-observation.component';
|
||||
import { FeatureListCroppingschemeComponent } from './components/feature-list-croppingscheme/feature-list-croppingscheme.component';
|
||||
import { FeatureListFeatureContainerComponent } from './components/feature-list-feature-container/feature-list-feature-container.component';
|
||||
import { FeatureListFeatureCropfieldComponent } from './components/feature-list-feature-cropfield/feature-list-feature-cropfield.component';
|
||||
import { FeatureListFeatureCroppingschemeComponent } from './components/feature-list-feature-croppingscheme/feature-list-feature-croppingscheme.component';
|
||||
import { AbstractFeatureListFeatureComponent, FeatureListFeatureComponent } from './components/feature-list-feature/feature-list-feature.component';
|
||||
import { AbstractFeatureListComponent, FeatureListComponent } from './components/feature-list/feature-list.component';
|
||||
import { GeometryThumbnailComponent } from './components/feature-thumbnail/feature-thumbnail.component';
|
||||
import { ForChild } from './components/for-item/for-child.decorator';
|
||||
import { ForItemType } from './components/for-item/for-itemtype.decorator';
|
||||
import { ForPackage } from './components/for-item/for-package.decorator';
|
||||
import { ForSourceTask } from './components/for-item/for-sourcetask.decorator';
|
||||
import { ifZoomToShowDirective } from './components/if-zoom-to-show/if-zoom-to-show.directive';
|
||||
import { ItemListItemContainerComponent } from './components/item-list-item-container/item-list-item-container.component';
|
||||
import { AbstractItemListItemComponent, AbstractItemWidgetComponent, ItemListItemComponent } from './components/item-list-item/item-list-item.component';
|
||||
import { AbstractItemListComponent, ItemListComponent } from './components/item-list/item-list.component';
|
||||
import { ItemWidgetListComponent } from './components/item-widget-list/item-widget-list.component';
|
||||
import { LayerSwitcher } from './components/layer-switcher/layer-switcher.component';
|
||||
import { HistogramDetailsComponent } from './components/legend/histogram-details/histogram-details.component';
|
||||
import { LegendComponent } from './components/legend/legend.component';
|
||||
import { StatisticsDetailsComponent } from './components/legend/statistics-details/statistics-details.component';
|
||||
import { MapSearchComponent } from './components/map-search/map-search.component';
|
||||
import { MapComponent } from './components/map/map.component';
|
||||
import { MetaDataModalComponent } from './components/meta-data-modal/meta-data-modal.component';
|
||||
import { SelectPeriodModalComponent } from './components/select-period-modal/select-period-modal.component';
|
||||
import { MapComponent } from './components/map/map.component';
|
||||
import { MapSearchComponent } from './components/map-search/map-search.component';
|
||||
import { MapRoutingModule } from './common-map-routing.module';
|
||||
import { LegendComponent } from './components/legend/legend.component';
|
||||
import { LayerVectorImageComponent } from './components/aol/layer-vector-image/layer-vector-image.component';
|
||||
import {FeatureIconService} from './services/feature-icon.service';
|
||||
import { GeolocationService } from './services/geolocation.service';
|
||||
import {DeviceOrientationService} from './services/device-orientation.service';
|
||||
import { TemporalService} from './services/temporal.service';
|
||||
import { SelectedItemContainerComponent } from './components/selected-item-container/selected-item-container.component';
|
||||
import { SelectedItemCropfieldComponent } from './components/selected-item-cropfield/selected-item-cropfield.component';
|
||||
import { SelectedItemGeotiffComponent } from './components/selected-item-geotiff/selected-item-geotiff.component';
|
||||
import { SelectedItemShapeComponent } from './components/selected-item-shape/selected-item-shape.component';
|
||||
import { SelectedItemTemporalComponent } from './components/selected-item-temporal/selected-item-temporal.component';
|
||||
import { AbstractSelectedItemComponent, SelectedItemComponent } from './components/selected-item/selected-item.component';
|
||||
import { WidgetHostDirective } from './components/widget-host/widget-host.directive';
|
||||
import { WidgetStatusComponent } from './components/widget-status/widget-status.component';
|
||||
import { ForChild} from './components/for-item/for-child.decorator';
|
||||
import {ForItemType } from './components/for-item/for-itemtype.decorator';
|
||||
import { ForSourceTask} from './components/for-item/for-sourcetask.decorator';
|
||||
import { ForPackage } from './components/for-item/for-package.decorator';
|
||||
import { PanToLocation} from './components/aol/pan-to-location/pan-to-location.component';
|
||||
import {LayerSwitcher} from './components/layer-switcher/layer-switcher.component';
|
||||
import {HistogramDetailsComponent} from './components/legend/histogram-details/histogram-details.component';
|
||||
import {StatisticsDetailsComponent} from './components/legend/statistics-details/statistics-details.component';
|
||||
import { ifZoomToShowDirective} from './components/if-zoom-to-show/if-zoom-to-show.directive';
|
||||
import { ZoomToShowAlert} from './components/zoom-to-show-alert/zoom-to-show-alert.component';
|
||||
import { LayerValuesComponent } from './components/aol/layer-values/layer-values.component';
|
||||
import { GeometryThumbnailComponent } from './components/feature-thumbnail/feature-thumbnail.component';
|
||||
import { ZoomToShowAlert } from './components/zoom-to-show-alert/zoom-to-show-alert.component';
|
||||
import { DeviceOrientationService } from './services/device-orientation.service';
|
||||
import { FeatureIconService } from './services/feature-icon.service';
|
||||
import { GeolocationService } from './services/geolocation.service';
|
||||
import { TemporalService } from './services/temporal.service';
|
||||
|
||||
export function LocalStorageSync(reducer: ActionReducer<any>): ActionReducer<any> {
|
||||
const r = function(state, action) {
|
||||
@@ -104,184 +105,130 @@ export function LocalStorageSync(reducer: ActionReducer<any>): ActionReducer<any
|
||||
const metaReducers: Array<MetaReducer<any, any>> = [LocalStorageSync];
|
||||
|
||||
export {
|
||||
mapEffects,
|
||||
mapReducers,
|
||||
mapActions,
|
||||
ZoomToExtentComponent,
|
||||
ItemVectorSourceComponent,
|
||||
ItemLayersComponent,
|
||||
FileDropTargetComponent,
|
||||
MapComponent,
|
||||
MetaDataModalComponent,
|
||||
RotationResetComponent,
|
||||
MapSearchComponent,
|
||||
SelectPeriodModalComponent,
|
||||
LayerListComponent,
|
||||
LegendComponent,
|
||||
LayerVectorImageComponent,
|
||||
FeatureListComponent,
|
||||
WidgetHostDirective,
|
||||
FeatureListContainerComponent,
|
||||
FeatureListCroppingschemeComponent,
|
||||
FeatureListCropfieldComponent,
|
||||
FeatureListFeatureContainerComponent,
|
||||
FeatureListFeatureComponent,
|
||||
FeatureListFeatureCroppingschemeComponent,
|
||||
FeatureListFeatureCropfieldComponent,
|
||||
SelectedItemContainerComponent,
|
||||
SelectedItemComponent,
|
||||
SelectedItemCropfieldComponent,
|
||||
SelectedItemGeotiffComponent,
|
||||
SelectedItemTemporalComponent,
|
||||
SelectedItemShapeComponent,
|
||||
ItemListItemComponent,
|
||||
ItemListItemContainerComponent,
|
||||
ItemListComponent,
|
||||
ItemWidgetListComponent,
|
||||
WidgetStatusComponent,
|
||||
GpsLocation,
|
||||
PanToLocation,
|
||||
LayerSwitcher,
|
||||
AbstractFeatureListComponent,
|
||||
AbstractFeatureListFeatureComponent,
|
||||
AbstractSelectedItemComponent,
|
||||
AbstractItemWidgetComponent,
|
||||
AbstractItemListItemComponent,
|
||||
AbstractItemListComponent,
|
||||
FeatureIconService,
|
||||
GeolocationService,
|
||||
DeviceOrientationService,
|
||||
TemporalService,
|
||||
IMapState,
|
||||
ISelectedFeatures,
|
||||
IItemLayer,
|
||||
ItemLayer,
|
||||
IPeriodState,
|
||||
ForChild,
|
||||
ForItemType,
|
||||
ForSourceTask,
|
||||
ForPackage ,
|
||||
ITemporalItemLayer,
|
||||
TemporalItemLayer,
|
||||
ifZoomToShowDirective,
|
||||
ZoomToShowAlert,
|
||||
IClickedFeature,
|
||||
GeometryThumbnailComponent
|
||||
}
|
||||
AbstractFeatureListFeatureComponent, AbstractItemListComponent, AbstractItemListItemComponent, AbstractItemWidgetComponent, AbstractSelectedItemComponent, DeviceOrientationService, FeatureIconService, FeatureListComponent, FeatureListContainerComponent, FeatureListCropfieldComponent, FeatureListObservationComponent, FeatureListCroppingschemeComponent, FeatureListFeatureComponent, FeatureListFeatureContainerComponent, FeatureListFeatureCropfieldComponent, FeatureListFeatureCroppingschemeComponent, FileDropTargetComponent, ForChild,
|
||||
ForItemType, ForPackage, ForSourceTask, GeolocationService, GeometryThumbnailComponent, GpsLocation, IClickedFeature, ifZoomToShowDirective, IItemLayer, IMapState, IPeriodState, ISelectedFeatures, ItemLayer, ItemLayersComponent, ItemListComponent, ItemListItemComponent,
|
||||
ItemListItemContainerComponent, ITemporalItemLayer, ItemVectorSourceComponent, ItemWidgetListComponent, LayerListComponent, LayerSwitcher, LayerVectorImageComponent, LegendComponent, mapActions, MapComponent, mapEffects,
|
||||
mapReducers, MapSearchComponent, MetaDataModalComponent, PanToLocation, RotationResetComponent, SelectedItemComponent, SelectedItemContainerComponent, SelectedItemCropfieldComponent,
|
||||
SelectedItemGeotiffComponent, SelectedItemShapeComponent, SelectedItemTemporalComponent, SelectPeriodModalComponent, TemporalItemLayer, TemporalService, WidgetHostDirective, WidgetStatusComponent, ZoomToExtentComponent, ZoomToShowAlert
|
||||
};
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
AngularOpenlayersModule,
|
||||
MapRoutingModule,
|
||||
StoreModule.forFeature(MODULE_NAME, mapReducers.reducer, { metaReducers: metaReducers }),
|
||||
EffectsModule.forFeature([mapEffects.MapEffects]),
|
||||
NgbModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
AppCommonModule
|
||||
],
|
||||
declarations: [
|
||||
ZoomToExtentComponent,
|
||||
ItemVectorSourceComponent,
|
||||
ItemLayersComponent,
|
||||
FileDropTargetComponent,
|
||||
MapComponent,
|
||||
MetaDataModalComponent,
|
||||
RotationResetComponent,
|
||||
MapSearchComponent,
|
||||
SelectPeriodModalComponent,
|
||||
LayerListComponent,
|
||||
LegendComponent,
|
||||
LayerVectorImageComponent,
|
||||
FeatureListComponent,
|
||||
WidgetHostDirective,
|
||||
FeatureListContainerComponent,
|
||||
FeatureListCroppingschemeComponent,
|
||||
FeatureListCropfieldComponent,
|
||||
FeatureListFeatureContainerComponent,
|
||||
FeatureListFeatureComponent,
|
||||
FeatureListFeatureCroppingschemeComponent,
|
||||
FeatureListFeatureCropfieldComponent,
|
||||
SelectedItemContainerComponent,
|
||||
SelectedItemComponent,
|
||||
SelectedItemCropfieldComponent,
|
||||
SelectedItemGeotiffComponent,
|
||||
SelectedItemTemporalComponent,
|
||||
SelectedItemShapeComponent,
|
||||
ItemListItemComponent,
|
||||
ItemListItemContainerComponent,
|
||||
ItemListComponent,
|
||||
ItemWidgetListComponent,
|
||||
WidgetStatusComponent,
|
||||
GpsLocation,
|
||||
PanToLocation,
|
||||
LayerSwitcher,
|
||||
HistogramDetailsComponent,
|
||||
StatisticsDetailsComponent,
|
||||
ifZoomToShowDirective,
|
||||
ZoomToShowAlert,
|
||||
LayerValuesComponent,
|
||||
GeometryThumbnailComponent
|
||||
],
|
||||
exports: [
|
||||
ItemVectorSourceComponent,
|
||||
ItemLayersComponent,
|
||||
FileDropTargetComponent,
|
||||
MetaDataModalComponent,
|
||||
MapComponent,
|
||||
GpsLocation,
|
||||
PanToLocation,
|
||||
LayerSwitcher,
|
||||
FeatureListFeatureComponent,
|
||||
FeatureListFeatureCropfieldComponent,
|
||||
FeatureListFeatureCroppingschemeComponent,
|
||||
SelectedItemContainerComponent,
|
||||
SelectedItemComponent,
|
||||
SelectedItemCropfieldComponent,
|
||||
SelectedItemGeotiffComponent,
|
||||
SelectedItemTemporalComponent,
|
||||
SelectedItemShapeComponent,
|
||||
ItemListItemComponent,
|
||||
ItemListItemContainerComponent,
|
||||
ItemListComponent,
|
||||
ItemWidgetListComponent,
|
||||
WidgetStatusComponent,
|
||||
RotationResetComponent,
|
||||
MapSearchComponent,
|
||||
SelectPeriodModalComponent,
|
||||
LayerListComponent,
|
||||
LegendComponent,
|
||||
LayerVectorImageComponent,
|
||||
FeatureListComponent,
|
||||
WidgetHostDirective,
|
||||
FeatureListContainerComponent,
|
||||
FeatureListCroppingschemeComponent,
|
||||
FeatureListCropfieldComponent,
|
||||
FeatureListFeatureContainerComponent,
|
||||
ZoomToExtentComponent,
|
||||
ifZoomToShowDirective,
|
||||
ZoomToShowAlert,
|
||||
GeometryThumbnailComponent
|
||||
],
|
||||
providers: [
|
||||
FeatureIconService,
|
||||
GeolocationService,
|
||||
DeviceOrientationService,
|
||||
TemporalService,
|
||||
{ provide: AbstractFeatureListComponent, useClass: FeatureListCroppingschemeComponent, multi: true },
|
||||
{ provide: AbstractFeatureListComponent, useClass: FeatureListCropfieldComponent, multi: true },
|
||||
{ provide: AbstractFeatureListFeatureComponent, useClass: FeatureListFeatureComponent, multi: true },
|
||||
{ provide: AbstractFeatureListFeatureComponent, useClass: FeatureListFeatureCroppingschemeComponent, multi: true },
|
||||
{ provide: AbstractFeatureListFeatureComponent, useClass: FeatureListFeatureCropfieldComponent, multi: true },
|
||||
{ provide: AbstractSelectedItemComponent, useClass: SelectedItemComponent, multi: true },
|
||||
{ provide: AbstractSelectedItemComponent, useClass: SelectedItemCropfieldComponent, multi: true },
|
||||
{ provide: AbstractSelectedItemComponent, useClass: SelectedItemGeotiffComponent, multi: true },
|
||||
{ provide: AbstractSelectedItemComponent, useClass: SelectedItemTemporalComponent, multi: true },
|
||||
{ provide: AbstractSelectedItemComponent, useClass: SelectedItemShapeComponent, multi: true },
|
||||
{ provide: AbstractItemListItemComponent, useClass: ItemListItemComponent, multi: true },
|
||||
{ provide: AbstractItemListComponent, useClass: ItemListComponent, multi: true }
|
||||
]
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
AngularOpenlayersModule,
|
||||
MapRoutingModule,
|
||||
StoreModule.forFeature(MODULE_NAME, mapReducers.reducer, { metaReducers: metaReducers }),
|
||||
EffectsModule.forFeature([mapEffects.MapEffects]),
|
||||
NgbModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
AppCommonModule
|
||||
],
|
||||
declarations: [
|
||||
ZoomToExtentComponent,
|
||||
ItemVectorSourceComponent,
|
||||
ItemLayersComponent,
|
||||
FileDropTargetComponent,
|
||||
MapComponent,
|
||||
MetaDataModalComponent,
|
||||
RotationResetComponent,
|
||||
MapSearchComponent,
|
||||
SelectPeriodModalComponent,
|
||||
LayerListComponent,
|
||||
LegendComponent,
|
||||
LayerVectorImageComponent,
|
||||
FeatureListComponent,
|
||||
WidgetHostDirective,
|
||||
FeatureListContainerComponent,
|
||||
FeatureListCroppingschemeComponent,
|
||||
FeatureListCropfieldComponent,
|
||||
FeatureListObservationComponent,
|
||||
FeatureListFeatureContainerComponent,
|
||||
FeatureListFeatureComponent,
|
||||
FeatureListFeatureCroppingschemeComponent,
|
||||
FeatureListFeatureCropfieldComponent,
|
||||
SelectedItemContainerComponent,
|
||||
SelectedItemComponent,
|
||||
SelectedItemCropfieldComponent,
|
||||
SelectedItemGeotiffComponent,
|
||||
SelectedItemTemporalComponent,
|
||||
SelectedItemShapeComponent,
|
||||
ItemListItemComponent,
|
||||
ItemListItemContainerComponent,
|
||||
ItemListComponent,
|
||||
ItemWidgetListComponent,
|
||||
WidgetStatusComponent,
|
||||
GpsLocation,
|
||||
PanToLocation,
|
||||
LayerSwitcher,
|
||||
HistogramDetailsComponent,
|
||||
StatisticsDetailsComponent,
|
||||
ifZoomToShowDirective,
|
||||
ZoomToShowAlert,
|
||||
LayerValuesComponent,
|
||||
GeometryThumbnailComponent
|
||||
],
|
||||
exports: [
|
||||
ItemVectorSourceComponent,
|
||||
ItemLayersComponent,
|
||||
FileDropTargetComponent,
|
||||
MetaDataModalComponent,
|
||||
MapComponent,
|
||||
GpsLocation,
|
||||
PanToLocation,
|
||||
LayerSwitcher,
|
||||
FeatureListFeatureComponent,
|
||||
FeatureListFeatureCropfieldComponent,
|
||||
FeatureListFeatureCroppingschemeComponent,
|
||||
SelectedItemContainerComponent,
|
||||
SelectedItemComponent,
|
||||
SelectedItemCropfieldComponent,
|
||||
SelectedItemGeotiffComponent,
|
||||
SelectedItemTemporalComponent,
|
||||
SelectedItemShapeComponent,
|
||||
ItemListItemComponent,
|
||||
ItemListItemContainerComponent,
|
||||
ItemListComponent,
|
||||
ItemWidgetListComponent,
|
||||
WidgetStatusComponent,
|
||||
RotationResetComponent,
|
||||
MapSearchComponent,
|
||||
SelectPeriodModalComponent,
|
||||
LayerListComponent,
|
||||
LegendComponent,
|
||||
LayerVectorImageComponent,
|
||||
FeatureListComponent,
|
||||
WidgetHostDirective,
|
||||
FeatureListContainerComponent,
|
||||
FeatureListCroppingschemeComponent,
|
||||
FeatureListCropfieldComponent,
|
||||
FeatureListObservationComponent,
|
||||
FeatureListFeatureContainerComponent,
|
||||
ZoomToExtentComponent,
|
||||
ifZoomToShowDirective,
|
||||
ZoomToShowAlert,
|
||||
GeometryThumbnailComponent
|
||||
],
|
||||
providers: [
|
||||
FeatureIconService,
|
||||
GeolocationService,
|
||||
DeviceOrientationService,
|
||||
TemporalService,
|
||||
{ provide: AbstractFeatureListComponent, useClass: FeatureListCroppingschemeComponent, multi: true },
|
||||
{ provide: AbstractFeatureListComponent, useClass: FeatureListCropfieldComponent, multi: true },
|
||||
{ provide: AbstractFeatureListComponent, useClass: FeatureListObservationComponent, multi: true },
|
||||
{ provide: AbstractFeatureListFeatureComponent, useClass: FeatureListFeatureComponent, multi: true },
|
||||
{ provide: AbstractFeatureListFeatureComponent, useClass: FeatureListFeatureCroppingschemeComponent, multi: true },
|
||||
{ provide: AbstractFeatureListFeatureComponent, useClass: FeatureListFeatureCropfieldComponent, multi: true },
|
||||
{ provide: AbstractSelectedItemComponent, useClass: SelectedItemComponent, multi: true },
|
||||
{ provide: AbstractSelectedItemComponent, useClass: SelectedItemCropfieldComponent, multi: true },
|
||||
{ provide: AbstractSelectedItemComponent, useClass: SelectedItemGeotiffComponent, multi: true },
|
||||
{ provide: AbstractSelectedItemComponent, useClass: SelectedItemTemporalComponent, multi: true },
|
||||
{ provide: AbstractSelectedItemComponent, useClass: SelectedItemShapeComponent, multi: true },
|
||||
{ provide: AbstractItemListItemComponent, useClass: ItemListItemComponent, multi: true },
|
||||
{ provide: AbstractItemListComponent, useClass: ItemListComponent, multi: true }
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, Input, OnDestroy, OnInit, EventEmitter, Output, Inject } from '@angular/core';
|
||||
import { MapComponent } from 'ngx-openlayers';
|
||||
import { MapComponent } from '@farmmaps/ng-openlayers';
|
||||
|
||||
import * as proj from 'ol/proj';
|
||||
import {Point,Geometry} from 'ol/geom';
|
||||
@@ -14,8 +14,9 @@ export interface IDroppedFile {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-file-drop-target',
|
||||
template: ''
|
||||
selector: 'fm-map-file-drop-target',
|
||||
template: '',
|
||||
standalone: false
|
||||
})
|
||||
export class FileDropTargetComponent implements OnInit, OnDestroy {
|
||||
element: Element;
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Component, OnInit, Input, ViewChild, ElementRef, OnChanges, SimpleChanges ,Host} from '@angular/core';
|
||||
import { MapComponent } from 'ngx-openlayers';
|
||||
import { MapComponent } from '@farmmaps/ng-openlayers';
|
||||
import Overlay from 'ol/Overlay';
|
||||
import { fromLonLat, toLonLat } from 'ol/proj';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-gps-location',
|
||||
templateUrl: './gps-location.component.html',
|
||||
styleUrls: ['./gps-location.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-gps-location',
|
||||
templateUrl: './gps-location.component.html',
|
||||
styleUrls: ['./gps-location.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class GpsLocation implements OnInit,OnChanges{
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, Host, Input, Output, EventEmitter,OnDestroy, OnInit, OnChanges, SimpleChanges, forwardRef } from '@angular/core';
|
||||
import { LayerGroupComponent, MapComponent } from 'ngx-openlayers';
|
||||
import { LayerGroupComponent, MapComponent } from '@farmmaps/ng-openlayers';
|
||||
import { ItemService,IItem,AppConfig } from '@farmmaps/common';
|
||||
import { IItemLayer, ITemporalItemLayer} from '../../../models/item.layer';
|
||||
import { ILayerData} from '../../../models/layer.data';
|
||||
@@ -19,13 +19,15 @@ import VectorTileLayer from 'ol/layer/VectorTile';
|
||||
import {GeoJSON,MVT} from 'ol/format';
|
||||
import { Geometry } from 'ol/geom';
|
||||
import BaseLayer from 'ol/layer/Base';
|
||||
import Feature from 'ol/Feature';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-item-layers',
|
||||
template: `<ng-content></ng-content>`,
|
||||
providers: [
|
||||
{ provide: LayerGroupComponent, useExisting: forwardRef(() => ItemLayersComponent) }
|
||||
]
|
||||
@Component({
|
||||
selector: 'fm-map-item-layers',
|
||||
template: `<ng-content></ng-content>`,
|
||||
providers: [
|
||||
{ provide: LayerGroupComponent, useExisting: forwardRef(() => ItemLayersComponent) }
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
|
||||
export class ItemLayersComponent extends LayerGroupComponent implements OnChanges, OnInit,OnDestroy {
|
||||
@@ -180,9 +182,9 @@ export class ItemLayersComponent extends LayerGroupComponent implements OnChange
|
||||
const source = new VectorSource({
|
||||
strategy: loadingstrategy.bbox,
|
||||
loader: function (extent: Extent, resolution: number, projection: Projection) {
|
||||
const source = this as VectorSource<Geometry>;
|
||||
const source = this as VectorSource<Feature<Geometry>>;
|
||||
__this.itemService.getItemFeatures(item.code, extent, projection.getCode(), layerIndex).subscribe(function (data) {
|
||||
const features = format.readFeatures(data);
|
||||
const features = format.readFeatures(data).filter(feature => feature instanceof Feature) as Feature[];
|
||||
for (const f of features) {
|
||||
if (f.get("code")) {
|
||||
f.setId(f.get("code"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, Host, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, forwardRef, Inject, InjectionToken, OnDestroy, LOCALE_ID } from '@angular/core';
|
||||
import { LayerVectorComponent, SourceVectorComponent, MapComponent } from 'ngx-openlayers';
|
||||
import { LayerVectorComponent, SourceVectorComponent, MapComponent } from '@farmmaps/ng-openlayers';
|
||||
import { ItemService, ItemTypeService, IItem, IItemType, FolderService } from '@farmmaps/common';
|
||||
|
||||
import { Feature } from 'ol';
|
||||
@@ -21,15 +21,16 @@ import { Subscription } from 'rxjs';
|
||||
import { getCenter } from 'ol/extent';
|
||||
import { formatNumber } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-item-source-vector',
|
||||
template: `<ng-content></ng-content>`,
|
||||
providers: [
|
||||
{ provide: SourceVectorComponent, useExisting: forwardRef(() => ItemVectorSourceComponent) }
|
||||
]
|
||||
@Component({
|
||||
selector: 'fm-map-item-source-vector',
|
||||
template: `<ng-content></ng-content>`,
|
||||
providers: [
|
||||
{ provide: SourceVectorComponent, useExisting: forwardRef(() => ItemVectorSourceComponent) }
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class ItemVectorSourceComponent extends SourceVectorComponent implements OnInit, OnDestroy, OnChanges {
|
||||
instance: Vector<Geometry>;
|
||||
instance: Vector<Feature<Geometry>>;
|
||||
private _format: GeoJSON;
|
||||
private _select: Select;
|
||||
private _hoverSelect: Select;
|
||||
@@ -83,6 +84,7 @@ export class ItemVectorSourceComponent extends SourceVectorComponent implements
|
||||
ngOnInit() {
|
||||
this.sub = this.folderService.getFolder('my_settings').subscribe(
|
||||
userSettingsRoot => {
|
||||
if (userSettingsRoot == undefined) return;
|
||||
this.itemService.getChildItemList(userSettingsRoot.code, 'vnd.farmmaps.itemtype.settings.general').subscribe(
|
||||
items => {
|
||||
if (items && items.length > 0 && items[0].data?.displayMapFeatureSettings) {
|
||||
|
||||
@@ -1,31 +1,50 @@
|
||||
<div>
|
||||
<div class="layerlist" *ngIf="itemLayers.length > 0;else noLayers">
|
||||
<div class="list-group">
|
||||
<div *ngFor="let itemLayer of itemLayers" class="list-group-item list-group-item-action p-2 text-truncate" [ngClass]="{'active' : selectedLayer==itemLayer}">
|
||||
<div (click)="handleSelectLayer($event,itemLayer)" [title]="itemLayer.item.name">{{itemLayer.item.name}}</div>
|
||||
<div class="mt-1" *ngIf="selectedLayer==itemLayer && !baseLayers">
|
||||
<span class="btn-group">
|
||||
<a title="Toggle visibility"href="#" class="btn btn-light btn-sm" (click)="handleToggleVisibility($event,itemLayer)"><i class="fa" aria-hidden="true" [ngClass]="{'fa-eye':!itemLayer.visible,'fa-eye-slash':itemLayer.visible}"></i></a>
|
||||
<a title="Transparency 25%" *ngIf="itemLayer.visible" href="#" class="btn btn-light btn-sm" (click)="handleSetOpacity($event,itemLayer,0.25)">25%</a>
|
||||
<a title="Transparency 50%" *ngIf="itemLayer.visible" href="#" class="btn btn-light btn-sm" (click)="handleSetOpacity($event,itemLayer,0.5)">50%</a>
|
||||
<a title="Transparency 75%" *ngIf="itemLayer.visible" href="#" class="btn btn-light btn-sm" (click)="handleSetOpacity($event,itemLayer,0.75)">75%</a>
|
||||
<a title="No transparency" *ngIf="itemLayer.visible" href="#" class="btn btn-light btn-sm" (click)="handleSetOpacity($event,itemLayer,1)">100%</a>
|
||||
</span>
|
||||
<a href="#" title="Zoom to extent" class="btn btn-light btn-sm" (click)="handleZoomToExtent($event,itemLayer)"><i class="far fa-search-plus" aria-hidden="true"></i></a>
|
||||
<span *ngIf="firstLayer(itemLayer)"><a href="#" title="Toggle legend" class="btn btn-light btn-sm" (click)="itemLayer.legendVisible=toggleLegend($event,itemLayer.legendVisible)"><i class="far fa-chart-bar" aria-hidden="true"></i></a></span>
|
||||
<span *ngIf="!dataLayers" class="float-end"><a href="#" title="Remove overlay" class="btn btn-light btn-sm" (click)="handleDelete($event,itemLayer)"><i class="fas fa-layer-minus" aria-hidden="true"></i></a></span>
|
||||
</div>
|
||||
<div *ngIf="itemLayer.legendVisible">
|
||||
<div class="card legend">
|
||||
<fm-map-layer-legend [layer]="firstLayer(itemLayer)" (click)="handleLegendClick($event,itemLayer);" [histogramenabled]="true"></fm-map-layer-legend>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #noLayers>
|
||||
<div class="list-group">
|
||||
<div class="list-group-item" i18n>No layers</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
<div>
|
||||
@if (itemLayers.length > 0) {
|
||||
<div class="layerlist">
|
||||
<div class="list-group">
|
||||
@for (itemLayer of itemLayers; track itemLayer.item.code) {
|
||||
<div class="list-group-item list-group-item-action p-2 text-truncate" [ngClass]="{'active' : selectedLayer==itemLayer}">
|
||||
<div (click)="handleSelectLayer($event,itemLayer)" [title]="itemLayer.item.name">{{itemLayer.item.name}}</div>
|
||||
@if (selectedLayer==itemLayer && !baseLayers) {
|
||||
<div class="mt-1">
|
||||
<span class="btn-group">
|
||||
<a title="Toggle visibility"href="#" class="btn btn-light btn-sm" (click)="handleToggleVisibility($event,itemLayer)"><i class="fa" aria-hidden="true" [ngClass]="{'fa-eye':!itemLayer.visible,'fa-eye-slash':itemLayer.visible}"></i></a>
|
||||
@if (itemLayer.visible) {
|
||||
<a title="Transparency 25%" href="#" class="btn btn-light btn-sm" (click)="handleSetOpacity($event,itemLayer,0.25)">25%</a>
|
||||
}
|
||||
@if (itemLayer.visible) {
|
||||
<a title="Transparency 50%" href="#" class="btn btn-light btn-sm" (click)="handleSetOpacity($event,itemLayer,0.5)">50%</a>
|
||||
}
|
||||
@if (itemLayer.visible) {
|
||||
<a title="Transparency 75%" href="#" class="btn btn-light btn-sm" (click)="handleSetOpacity($event,itemLayer,0.75)">75%</a>
|
||||
}
|
||||
@if (itemLayer.visible) {
|
||||
<a title="No transparency" href="#" class="btn btn-light btn-sm" (click)="handleSetOpacity($event,itemLayer,1)">100%</a>
|
||||
}
|
||||
</span>
|
||||
<a href="#" title="Zoom to extent" class="btn btn-light btn-sm" (click)="handleZoomToExtent($event,itemLayer)"><i class="far fa-search-plus" aria-hidden="true"></i></a>
|
||||
@if (firstLayer(itemLayer)) {
|
||||
<span><a href="#" title="Toggle legend" class="btn btn-light btn-sm" (click)="itemLayer.legendVisible=toggleLegend($event,itemLayer.legendVisible)"><i class="far fa-chart-bar" aria-hidden="true"></i></a></span>
|
||||
}
|
||||
@if (!dataLayers) {
|
||||
<span class="float-end"><a href="#" title="Remove overlay" class="btn btn-light btn-sm" (click)="handleDelete($event,itemLayer)"><i class="fas fa-layer-minus" aria-hidden="true"></i></a></span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@if (itemLayer.legendVisible) {
|
||||
<div>
|
||||
<div class="card legend">
|
||||
<fm-map-layer-legend [layer]="firstLayer(itemLayer)" (click)="handleLegendClick($event,itemLayer);" [histogramenabled]="true"></fm-map-layer-legend>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="list-group">
|
||||
<div class="list-group-item" i18n>No layers</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component,Input,Output,EventEmitter } from '@angular/core';
|
||||
import { IItemLayer } from '../../../models/item.layer';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-layer-list',
|
||||
templateUrl: './layer-list.component.html',
|
||||
styleUrls: ['./layer-list.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-layer-list',
|
||||
templateUrl: './layer-list.component.html',
|
||||
styleUrls: ['./layer-list.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
|
||||
export class LayerListComponent {
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
<div #layerValues class="layer-values">
|
||||
<div class="cross" *ngIf="enabled$ | async">
|
||||
<div class="pointer"></div>
|
||||
<div class="values-container border border-dark rounded p-2" *ngIf="(layerValues$ | async ) as layers">
|
||||
<div class="lonlat pb-2 "><span class="font-weight-bold">{{lonlat$}}</span><i class="ms-2 fal fa-copy" (click)="copyToClipboard()"></i> </div>
|
||||
<ul class="value-list p-0 mb-0" *ngIf="layers.length>0 ;else no_data">
|
||||
<li class="border-top pt-1 pb-1 value" *ngFor="let layerValue of layers">
|
||||
<div>{{layerValue.layerName}}</div>
|
||||
<div>{{layerValue.date|date}}</div>
|
||||
<div><span *ngIf="layerValue.quantity"><span class="me-1">{{layerValue.quantity}}</span> </span><span class="me-1 font-weight-bold">{{getScaledValue(layerValue)}}</span><span>{{layerValue.unit}}</span></div>
|
||||
</li>
|
||||
</ul>
|
||||
<ng-template #no_data>
|
||||
<div i18n class="border-top pt-1 pb-1">No data at location</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (enabled$ | async) {
|
||||
<div class="cross" >
|
||||
<div class="pointer"></div>
|
||||
@if ((layerValues$ | async ); as layers) {
|
||||
<div class="values-container border border-dark rounded p-2">
|
||||
<div class="lonlat pb-2 "><span class="font-weight-bold">{{lonlat$}}</span><i class="ms-2 fal fa-copy" (click)="copyToClipboard()"></i> </div>
|
||||
@if (layers.length>0 ) {
|
||||
<ul class="value-list p-0 mb-0">
|
||||
@for (layerValue of layers; track $index) {
|
||||
<li class="border-top pt-1 pb-1 value">
|
||||
<div>{{layerValue.layerName}}</div>
|
||||
<div>{{layerValue.date|date}}</div>
|
||||
<div>@if (layerValue.quantity) {
|
||||
<span><span class="me-1">{{layerValue.quantity}}</span> </span>
|
||||
}<span class="me-1 font-weight-bold">{{getScaledValue(layerValue)}}</span><span>{{layerValue.unit}}</span></div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
} @else {
|
||||
<div i18n class="border-top pt-1 pb-1">No data at location</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { IItemLayer } from '../../../models/item.layer';
|
||||
import { Store } from '@ngrx/store';
|
||||
import * as mapReducers from '../../../reducers/map.reducer';
|
||||
import * as mapActions from '../../../actions/map.actions';
|
||||
import { MapComponent } from 'ngx-openlayers';
|
||||
import { MapComponent } from '@farmmaps/ng-openlayers';
|
||||
import { ILayervalue } from '../../../models/layer.value';
|
||||
import { Observable, interval, Subject } from 'rxjs';
|
||||
import { debounce, throttle } from 'rxjs/operators';
|
||||
@@ -14,9 +14,10 @@ import { GeoJSON, WKT } from 'ol/format';
|
||||
import { Point } from 'ol/geom';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-layer-values',
|
||||
templateUrl: './layer-values.component.html',
|
||||
styleUrls: ['./layer-values.component.scss']
|
||||
selector: 'fm-map-layer-values',
|
||||
templateUrl: './layer-values.component.html',
|
||||
styleUrls: ['./layer-values.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class LayerValuesComponent implements OnInit, AfterViewInit {
|
||||
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import { Component, OnDestroy, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { LayerVectorComponent, MapComponent } from 'ngx-openlayers';
|
||||
import { LayerVectorComponent, MapComponent } from '@farmmaps/ng-openlayers';
|
||||
import RenderType from 'ol/layer/Vector';
|
||||
import { Vector as VectorSource } from 'ol/source';
|
||||
import { Geometry } from 'ol/geom';
|
||||
import Feature from 'ol/Feature';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-aol-layer-vector-image',
|
||||
template: `
|
||||
selector: 'fm-map-aol-layer-vector-image',
|
||||
template: `
|
||||
<ng-content></ng-content>
|
||||
`,
|
||||
standalone: false
|
||||
})
|
||||
export class LayerVectorImageComponent extends LayerVectorComponent implements OnInit, OnDestroy, OnChanges {
|
||||
//public source: Vector;
|
||||
|
||||
@Input()
|
||||
renderMode: RenderType<VectorSource<Geometry>> | string = "image";
|
||||
renderMode: RenderType<VectorSource<Feature<Geometry>>> | string = "image";
|
||||
|
||||
constructor(map: MapComponent) {
|
||||
super(map);
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { Component, OnInit, Input, Host, OnChanges, SimpleChanges,ChangeDetectorRef } from '@angular/core';
|
||||
import { MapComponent } from 'ngx-openlayers';
|
||||
import { MapComponent } from '@farmmaps/ng-openlayers';
|
||||
import {IMapState} from '../../../models/map.state'
|
||||
import {View} from 'ol';
|
||||
import { fromLonLat } from 'ol/proj';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-pan-to-location',
|
||||
templateUrl: './pan-to-location.component.html',
|
||||
styleUrls: ['./pan-to-location.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-pan-to-location',
|
||||
templateUrl: './pan-to-location.component.html',
|
||||
styleUrls: ['./pan-to-location.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class PanToLocation implements OnInit,OnChanges{
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { Component, Host, Input, OnInit, ChangeDetectorRef } from '@angular/core';
|
||||
import { ViewComponent, MapComponent } from 'ngx-openlayers';
|
||||
import { ViewComponent, MapComponent } from '@farmmaps/ng-openlayers';
|
||||
|
||||
import {View} from 'ol';
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-rotation-reset',
|
||||
templateUrl: './rotation-reset.component.html',
|
||||
styleUrls: ['./rotation-reset.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-rotation-reset',
|
||||
templateUrl: './rotation-reset.component.html',
|
||||
styleUrls: ['./rotation-reset.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class RotationResetComponent implements OnInit {
|
||||
view: View;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Component, Host, Input, OnInit, OnChanges, SimpleChanges, forwardRef } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ViewComponent, MapComponent } from 'ngx-openlayers';
|
||||
import { ViewComponent, MapComponent } from '@farmmaps/ng-openlayers';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-zoom-to-extent',
|
||||
template: `<ng-content></ng-content>`
|
||||
@Component({
|
||||
selector: 'fm-map-zoom-to-extent',
|
||||
template: `<ng-content></ng-content>`,
|
||||
standalone: false
|
||||
})
|
||||
export class ZoomToExtentComponent implements OnChanges {
|
||||
view: ViewComponent;
|
||||
|
||||
@@ -10,10 +10,11 @@ import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-container',
|
||||
templateUrl: './feature-list-container.component.html',
|
||||
styleUrls: ['./feature-list-container.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-container',
|
||||
templateUrl: './feature-list-container.component.html',
|
||||
styleUrls: ['./feature-list-container.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class FeatureListContainerComponent {
|
||||
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
<div class="card border-0">
|
||||
<div class="card-body" *ngIf="(schemeItem|async);let schemeItem">
|
||||
<fm-back-button></fm-back-button>
|
||||
<h4 i18n>Farm</h4>
|
||||
<h3>{{schemeItem.name}}</h3>
|
||||
<div *ngIf="features;let features">
|
||||
<div class="cropfields">
|
||||
<div class="row m-0 ps-3 pe-3" *ngFor="let feature of features" [ngClass]="{'selected':isFeatureSelected(feature)}" (click)="handleFeatureClick(feature)" (mouseenter)="handleFeatureMouseEnter(feature)" (mouseleave)="handleFeatureMouseLeave(feature)">
|
||||
<fm-map-feature-list-feature-container [feature]="feature"></fm-map-feature-list-feature-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card border-0">
|
||||
@if ((schemeItem|async); as schemeItem) {
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<h4 i18n>Farm</h4>
|
||||
<h3>{{schemeItem.name}}</h3>
|
||||
@if (features; as features) {
|
||||
<div>
|
||||
<div class="cropfields">
|
||||
@for (feature of features; track $index) {
|
||||
<div class="row m-0 ps-3 pe-3" [ngClass]="{'selected':isFeatureSelected(feature)}" (click)="handleFeatureClick(feature)" (mouseenter)="handleFeatureMouseEnter(feature)" (mouseleave)="handleFeatureMouseLeave(feature)">
|
||||
<fm-map-feature-list-feature-container [feature]="feature"></fm-map-feature-list-feature-container>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -11,10 +11,11 @@ import { Observable } from 'rxjs';
|
||||
@ForChild()
|
||||
@ForItemType("vnd.farmmaps.itemtype.cropfield")
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-cropfield',
|
||||
templateUrl: './feature-list-cropfield.component.html',
|
||||
styleUrls: ['./feature-list-cropfield.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-cropfield',
|
||||
templateUrl: './feature-list-cropfield.component.html',
|
||||
styleUrls: ['./feature-list-cropfield.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class FeatureListCropfieldComponent extends AbstractFeatureListComponent implements OnInit {
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<h3><i class="far fa-farm"></i> <span i18n>Farms</span></h3>
|
||||
<div *ngIf="features;let features">
|
||||
<div class="farms">
|
||||
<div class="row m-0 ps-3 pe-3" *ngFor="let feature of features"[ngClass]="{'selected':isFeatureSelected(feature)}" (click)="handleFeatureClick(feature)" (mouseenter)="handleFeatureMouseEnter(feature)" (mouseleave)="handleFeatureMouseLeave(feature)">
|
||||
<fm-map-feature-list-feature-container [feature]="feature"></fm-map-feature-list-feature-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<h3><i class="far fa-farm"></i> <span i18n>Farms</span></h3>
|
||||
@if (features; as features) {
|
||||
<div>
|
||||
<div class="farms">
|
||||
@for (feature of features; track $index) {
|
||||
<div class="row m-0 ps-3 pe-3"[ngClass]="{'selected':isFeatureSelected(feature)}" (click)="handleFeatureClick(feature)" (mouseenter)="handleFeatureMouseEnter(feature)" (mouseleave)="handleFeatureMouseLeave(feature)">
|
||||
<fm-map-feature-list-feature-container [feature]="feature"></fm-map-feature-list-feature-container>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,10 +13,11 @@ import { Geometry} from 'ol/geom';
|
||||
|
||||
@ForItemType("vnd.farmmaps.itemtype.croppingscheme")
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-croppingscheme',
|
||||
templateUrl: './feature-list-croppingscheme.component.html',
|
||||
styleUrls: ['./feature-list-croppingscheme.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-croppingscheme',
|
||||
templateUrl: './feature-list-croppingscheme.component.html',
|
||||
styleUrls: ['./feature-list-croppingscheme.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class FeatureListCroppingschemeComponent extends AbstractFeatureListComponent {
|
||||
|
||||
|
||||
@@ -5,13 +5,14 @@ import { AbstractFeatureListFeatureComponent,FeatureListFeatureComponent } from
|
||||
import { WidgetHostDirective } from '../widget-host/widget-host.directive';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-feature-container',
|
||||
template: `
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-feature-container',
|
||||
template: `
|
||||
<div>
|
||||
<ng-template fm-map-widget-host></ng-template>
|
||||
</div>
|
||||
`
|
||||
`,
|
||||
standalone: false
|
||||
})
|
||||
export class FeatureListFeatureContainerComponent {
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<div *ngIf="feature;let feature" class="d-flex m-0">
|
||||
<div class="p-2">
|
||||
<div class="thumbnail">
|
||||
<fm-map-feature-thumbnail [feature]="feature"></fm-map-feature-thumbnail>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow p-2 overflow-hidden">
|
||||
<h1 class="card-title" title="{{feature.get('name')}}">{{feature.get('name')}}</h1>
|
||||
<div class="card-text"><span>{{areaInHa(feature)| number:'1.2-2'}}
|
||||
ha</span> <span>{{feature.get('cropTypeName')}}</span> </div>
|
||||
<div class="card-text"><span>{{feature.get('datadate')|date}}</span> -
|
||||
<span>{{feature.get('dataenddate')|date}}</span> </div>
|
||||
</div>
|
||||
</div>
|
||||
@if (feature; as feature) {
|
||||
<div class="d-flex m-0">
|
||||
<div class="p-2">
|
||||
<div class="thumbnail">
|
||||
<fm-map-feature-thumbnail [feature]="feature"></fm-map-feature-thumbnail>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow p-2 overflow-hidden">
|
||||
<h1 class="card-title" title="{{feature.get('name')}}">{{feature.get('name')}}</h1>
|
||||
<div class="card-text"><span>{{areaInHa(feature)| number:'1.2-2'}}
|
||||
ha</span> <span>{{feature.get('cropTypeName')}}</span> </div>
|
||||
<div class="card-text"><span>{{feature.get('datadate')|date}}</span> -
|
||||
<span>{{feature.get('dataenddate')|date}}</span> </div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -12,10 +12,11 @@ import {getArea} from 'ol/sphere';
|
||||
|
||||
@ForItemType("vnd.farmmaps.itemtype.cropfield")
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-feature-cropfield',
|
||||
templateUrl: './feature-list-feature-cropfield.component.html',
|
||||
styleUrls: ['./feature-list-feature-cropfield.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-feature-cropfield',
|
||||
templateUrl: './feature-list-feature-cropfield.component.html',
|
||||
styleUrls: ['./feature-list-feature-cropfield.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class FeatureListFeatureCropfieldComponent extends AbstractFeatureListFeatureComponent {
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<div *ngIf="feature;let feature" class="row m-0">
|
||||
@if (feature; as feature) {
|
||||
<div class="row m-0">
|
||||
<div class="col p-2">
|
||||
<h1 class="card-title" title="{{feature.get('name')}}">{{feature.get('name')}}</h1>
|
||||
<div class="card-text">{{feature.get('datadate')|date:'shortDate'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -10,9 +10,10 @@ import { ForItemType } from '../for-item/for-itemtype.decorator';
|
||||
@ForItemType("vnd.farmmaps.itemtype.croppingscheme")
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-feature-croppingscheme',
|
||||
templateUrl: './feature-list-feature-croppingscheme.component.html',
|
||||
styleUrls: ['./feature-list-feature-croppingscheme.component.scss']
|
||||
selector: 'fm-map-feature-list-feature-croppingscheme',
|
||||
templateUrl: './feature-list-feature-croppingscheme.component.html',
|
||||
styleUrls: ['./feature-list-feature-croppingscheme.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class FeatureListFeatureCroppingschemeComponent extends AbstractFeatureListFeatureComponent {
|
||||
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
<div *ngIf="feature;let feature" class="row m-0">
|
||||
@if (feature; as feature) {
|
||||
<div class="row m-0">
|
||||
<div class="col-3 w-25 m-0 p-2 thumbnail">
|
||||
<img *ngIf="feature.get('thumbnail')" [src]="config.getConfig('apiEndPoint') + '/api/v1/items/'+feature.get('code')+'/thumbnail'" />
|
||||
<div *ngIf="!feature.get('thumbnail')" [style.background-color]="itemTypeService.getColor(feature.get('itemType'))">
|
||||
<i [ngClass]="itemTypeService.getIcon(feature.get('itemType'))"></i>
|
||||
</div>
|
||||
@if (feature.get('thumbnail')) {
|
||||
<img [src]="config.getConfig('apiEndPoint') + '/api/v1/items/'+feature.get('code')+'/thumbnail'" />
|
||||
}
|
||||
@if (!feature.get('thumbnail')) {
|
||||
<div [style.background-color]="itemTypeService.getColor(feature.get('itemType'))">
|
||||
<i [ngClass]="itemTypeService.getIcon(feature.get('itemType'))"></i>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="col p-2">
|
||||
<h1 class="card-title" title="{{feature.get('name')}}"><i [ngClass]="itemTypeService.getIcon(feature.get('itemType'))" [style.color]="itemTypeService.getColor(feature.get('itemType'))"></i> {{feature.get('name')}}</h1>
|
||||
<div class="card-text">{{feature.get('datadate')|date:'shortDate'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -17,10 +17,11 @@ export abstract class AbstractFeatureListFeatureComponent {
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-feature',
|
||||
templateUrl: './feature-list-feature.component.html',
|
||||
styleUrls: ['./feature-list-feature.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-feature',
|
||||
templateUrl: './feature-list-feature.component.html',
|
||||
styleUrls: ['./feature-list-feature.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class FeatureListFeatureComponent extends AbstractFeatureListFeatureComponent {
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<div class="card border-0">
|
||||
@if ((schemeItem|async); as schemeItem) {
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<h4 i18n>Farm</h4>
|
||||
<h3>{{schemeItem.name}}</h3>
|
||||
@if (features; as features) {
|
||||
<div>
|
||||
<div class="cropfields">
|
||||
@for (feature of features; track $index) {
|
||||
<div class="row m-0 ps-3 pe-3" [ngClass]="{'selected':isFeatureSelected(feature)}" (click)="handleFeatureClick(feature)" (mouseenter)="handleFeatureMouseEnter(feature)" (mouseleave)="handleFeatureMouseLeave(feature)">
|
||||
<fm-map-feature-list-feature-container [feature]="feature"></fm-map-feature-list-feature-container>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -0,0 +1,20 @@
|
||||
fm-map-feature-list-feature-container {
|
||||
width:100%;
|
||||
pointer-events:none;
|
||||
}
|
||||
|
||||
.row {
|
||||
border-bottom: 1px solid var(--bs-gray-500);
|
||||
user-select: none;
|
||||
padding-left:1.5rem;
|
||||
}
|
||||
|
||||
.row.selected {
|
||||
background-color: var(--bs-gray-100);
|
||||
}
|
||||
|
||||
.cropfields {
|
||||
border-top: 1px solid var(--bs-gray-500);
|
||||
margin-left: -1.25rem;
|
||||
margin-right: -1.25rem;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Component, Injectable,AfterViewInit, OnInit,SimpleChanges, ChangeDetectorRef} from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { AbstractFeatureListComponent } from '../feature-list/feature-list.component';
|
||||
import {ForItemType } from '../for-item/for-itemtype.decorator';
|
||||
import {ForChild } from '../for-item/for-child.decorator';
|
||||
import { Store } from '@ngrx/store';
|
||||
import * as mapReducers from '../../reducers/map.reducer';
|
||||
import { commonReducers, ItemTypeService, IItem,ItemService } from '@farmmaps/common';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@ForChild()
|
||||
@ForItemType("vnd.farmmaps.itemtype.observation")
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list-observation',
|
||||
templateUrl: './feature-list-observation.component.html',
|
||||
styleUrls: ['./feature-list-observation.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class FeatureListObservationComponent extends AbstractFeatureListComponent implements OnInit {
|
||||
|
||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, location: Location, private itemService: ItemService) {
|
||||
super(store, itemTypeService,location);
|
||||
}
|
||||
|
||||
public schemeItem: Observable<IItem>
|
||||
|
||||
ngOnInit() {
|
||||
this.schemeItem = this.itemService.getItem(this.queryState.parentCode);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
<div *ngIf="features;let features">
|
||||
<fm-back-button></fm-back-button>
|
||||
<div class="row m-0 ps-3 pe-3" *ngFor="let feature of features" [ngClass]="{'selected':isFeatureSelected(feature)}" (click)="handleFeatureClick(feature)" (mouseenter)="handleFeatureMouseEnter(feature)" (mouseleave)="handleFeatureMouseLeave(feature)">
|
||||
<fm-map-feature-list-feature-container [feature]="feature"></fm-map-feature-list-feature-container>
|
||||
</div>
|
||||
</div>
|
||||
@if (features; as features) {
|
||||
<div>
|
||||
<fm-back-button></fm-back-button>
|
||||
@for (feature of features; track $index) {
|
||||
<div class="row m-0 ps-3 pe-3" [ngClass]="{'selected':isFeatureSelected(feature)}" (click)="handleFeatureClick(feature)" (mouseenter)="handleFeatureMouseEnter(feature)" (mouseleave)="handleFeatureMouseLeave(feature)">
|
||||
<fm-map-feature-list-feature-container [feature]="feature"></fm-map-feature-list-feature-container>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -57,10 +57,11 @@ export abstract class AbstractFeatureListComponent {
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list',
|
||||
templateUrl: './feature-list.component.html',
|
||||
styleUrls: ['./feature-list.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-feature-list',
|
||||
templateUrl: './feature-list.component.html',
|
||||
styleUrls: ['./feature-list.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class FeatureListComponent extends AbstractFeatureListComponent {
|
||||
|
||||
|
||||
@@ -6,9 +6,10 @@ import * as render from 'ol/render';
|
||||
import * as style from 'ol/style';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-feature-thumbnail',
|
||||
templateUrl: './feature-thumbnail.component.html',
|
||||
styleUrls: ['./feature-thumbnail.component.scss']
|
||||
selector: 'fm-map-feature-thumbnail',
|
||||
templateUrl: './feature-thumbnail.component.html',
|
||||
styleUrls: ['./feature-thumbnail.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class GeometryThumbnailComponent implements AfterViewInit {
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Directive, ViewContainerRef,TemplateRef,OnInit,Input, OnChanges } from '@angular/core';
|
||||
import { Layer } from 'ol/layer';
|
||||
import { Source } from 'ol/source';
|
||||
import { MapComponent } from 'ngx-openlayers';
|
||||
import { MapComponent } from '@farmmaps/ng-openlayers';
|
||||
|
||||
@Directive({
|
||||
selector: '[fmMapIfZoomToShow]',
|
||||
@Directive({
|
||||
selector: '[fmMapIfZoomToShow]',
|
||||
standalone: false
|
||||
})
|
||||
export class ifZoomToShowDirective implements OnInit {
|
||||
@Input()
|
||||
|
||||
@@ -4,13 +4,14 @@ import { WidgetHostDirective } from '../widget-host/widget-host.directive';
|
||||
import { IItem, IListItem } from '@farmmaps/common';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-item-list-item-container',
|
||||
template: `
|
||||
@Component({
|
||||
selector: 'fm-map-item-list-item-container',
|
||||
template: `
|
||||
<div style="height:100%">
|
||||
<ng-template fm-map-widget-host></ng-template>
|
||||
</div>
|
||||
`
|
||||
`,
|
||||
standalone: false
|
||||
})
|
||||
export class ItemListItemContainerComponent {
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<div *ngIf="item;let item" class="widget" [style.background-color]="itemTypeService.getColor(item.itemType)">
|
||||
<div class="align-middle icon" [ngClass]="itemTypeService.getIcon(item.itemType)"></div>
|
||||
<div class="title">{{item.name}}</div>
|
||||
</div>
|
||||
@if (item; as item) {
|
||||
<div class="widget" [style.background-color]="itemTypeService.getColor(item.itemType)">
|
||||
<div class="align-middle icon" [ngClass]="itemTypeService.getIcon(item.itemType)"></div>
|
||||
<div class="title">{{item.name}}</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -40,10 +40,11 @@ export abstract class AbstractItemWidgetComponent {
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-item-list-item',
|
||||
templateUrl: './item-list-item.component.html',
|
||||
styleUrls: ['./item-list-item.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-item-list-item',
|
||||
templateUrl: './item-list-item.component.html',
|
||||
styleUrls: ['./item-list-item.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class ItemListItemComponent extends AbstractItemListItemComponent {
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<div *ngIf="items;let items" class="widget-container pt-0">
|
||||
<div class="widget" *ngFor="let item of items" (click)="handleItemClick(item)">
|
||||
<div class="content">
|
||||
<fm-map-item-list-item-container [item]="item" class="item-container"></fm-map-item-list-item-container>
|
||||
</div>
|
||||
@if (items; as items) {
|
||||
<div class="widget-container pt-0">
|
||||
@for (item of items; track item.code) {
|
||||
<div class="widget" (click)="handleItemClick(item)">
|
||||
<div class="content">
|
||||
<fm-map-item-list-item-container [item]="item" class="item-container"></fm-map-item-list-item-container>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -28,9 +28,10 @@ export abstract class AbstractItemListComponent {
|
||||
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-item-list',
|
||||
templateUrl: './item-list.component.html',
|
||||
styleUrls: ['./item-list.component.scss']
|
||||
selector: 'fm-map-item-list',
|
||||
templateUrl: './item-list.component.html',
|
||||
styleUrls: ['./item-list.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class ItemListComponent extends AbstractItemListComponent {
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<div *ngIf="widgets;let widgets" class="widget-container pt-0">
|
||||
<div class="widget" *ngFor="let widget of widgets">
|
||||
<div class="content">
|
||||
<ng-template #widgetTemplate></ng-template>
|
||||
</div>
|
||||
@if (widgets; as widgets) {
|
||||
<div class="widget-container pt-0">
|
||||
@for (widget of widgets; track widget.item.code) {
|
||||
<div class="widget">
|
||||
<div class="content">
|
||||
<ng-template #widgetTemplate></ng-template>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -8,9 +8,10 @@ import { AbstractItemWidgetComponent } from '../item-list-item/item-list-item.co
|
||||
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-item-widget-list',
|
||||
templateUrl: './item-widget-list.component.html',
|
||||
styleUrls: ['./item-widget-list.component.scss']
|
||||
selector: 'fm-map-item-widget-list',
|
||||
templateUrl: './item-widget-list.component.html',
|
||||
styleUrls: ['./item-widget-list.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class ItemWidgetListComponent implements AfterViewInit {
|
||||
|
||||
|
||||
@@ -1,32 +1,39 @@
|
||||
<div class="btn btn-outline-primary layer-switcher" (click)="handleClick($event)">
|
||||
<i class="fal fa-layer-group"></i>
|
||||
<div class="layers hidden" [ngClass]="{'hidden':!(showLayerSwitcher|async)}" (click)="$event.stopPropagation();">
|
||||
<div class="card layers-card m-1">
|
||||
<div class="card-header">
|
||||
<span i18n>Layers</span>
|
||||
<i class="float-end fas fa-times" (click)="close($event)"></i>
|
||||
</div>
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item py-0">
|
||||
<span><i class="fal fa-layer-group" aria-hidden="true"></i> <span i18n>Base maps</span></span>
|
||||
<div class="mb-4">
|
||||
<fm-map-layer-list [baseLayers]="true" [itemLayers]="baseLayers|async" [selectedLayer]="selectedBaseLayer|async" (onSelectLayer)="handleSelectBaseLayer($event)"></fm-map-layer-list>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item py-0">
|
||||
<span><i class="fal fa-layer-group" aria-hidden="true"></i> <span i18n>Overlays</span></span>
|
||||
<div class="mb-4">
|
||||
<fm-map-layer-list [itemLayers]="overlayLayers|async" [selectedLayer]="selectedOverlayLayer|async" (onDelete)="handleOnDelete($event)" (onToggleVisibility)="handleOnToggleVisibility($event)" (onSetOpacity)="handleOnSetOpacity($event)" (onZoomToExtent)="handleZoomToExtent($event)" (onSelectLayer)="handleSelectOverlayLayer($event)"></fm-map-layer-list>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item py-0" *ngIf="selectedItemLayer$ | async as selectedItemLayer">
|
||||
<span><i class="fal fa-layer-group" aria-hidden="true"></i> <span i18n>Data</span><span class="slideButton"><a href="#" title="Compare" class="btn btn-light btn-sm" (click)="handleToggleShowDatalayerSlide($event)"><i class="fal fa-sliders-h-square"></i></a></span></span>
|
||||
<div class="mb-4">
|
||||
<fm-map-layer-list [dataLayers]="true" [itemLayers]="[selectedItemLayer]" [selectedLayer]="selectedItemLayer" (onToggleVisibility)="handleOnToggleVisibility($event)" (onSetOpacity)="handleOnSetOpacity($event)" (onZoomToExtent)="handleZoomToExtent($event)" (onSelectLayer)="handleSelectOverlayLayer($event)"></fm-map-layer-list>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn btn-outline-primary layer-switcher" (click)="handleClick($event)">
|
||||
<i class="fal fa-layer-group"></i>
|
||||
<div class="layers hidden" [ngClass]="{'hidden':!(showLayerSwitcher|async)}" (click)="$event.stopPropagation();">
|
||||
<div class="card layers-card m-1">
|
||||
<div class="card-header">
|
||||
<span i18n>Layers</span>
|
||||
<i class="float-end fas fa-times" (click)="close($event)"></i>
|
||||
</div>
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item py-0">
|
||||
<span><i class="fal fa-layer-group" aria-hidden="true"></i> <span i18n>Base maps</span></span>
|
||||
<div class="mb-4">
|
||||
<fm-map-layer-list [baseLayers]="true" [itemLayers]="baseMaps|async" [selectedLayer]="selectedBaseLayer|async" (onSelectLayer)="handleSelectBaseLayer($event)"></fm-map-layer-list>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item py-0">
|
||||
<span><i class="fal fa-layer-group" aria-hidden="true"></i> <span i18n>Overlays</span></span>
|
||||
<div class="mb-4">
|
||||
<fm-map-layer-list [itemLayers]="overlayLayers|async" [selectedLayer]="selectedOverlayLayer|async" (onDelete)="handleOnDelete($event)" (onToggleVisibility)="handleOnToggleVisibility($event)" (onSetOpacity)="handleOnSetOpacity($event)" (onZoomToExtent)="handleZoomToExtent($event)" (onSelectLayer)="handleSelectOverlayLayer($event)"></fm-map-layer-list>
|
||||
</div>
|
||||
</li>
|
||||
@if (selectedItemLayer$ | async; as selectedItemLayer) {
|
||||
<li class="nav-item py-0">
|
||||
<span><i class="fal fa-layer-group" aria-hidden="true"></i> <span i18n>Overlay slider</span><span class="slideButton"><a href="#" title="Compare" class="btn btn-light btn-sm" (click)="handleToggleShowDatalayerSlide($event)"><i class="fal fa-sliders-h-square"></i></a></span></span>
|
||||
<div class="mb-4">
|
||||
<fm-map-layer-list [dataLayers]="true" [itemLayers]="[selectedItemLayer]" [selectedLayer]="selectedItemLayer" (onToggleVisibility)="handleOnToggleVisibility($event)" (onSetOpacity)="handleOnSetOpacity($event)" (onZoomToExtent)="handleZoomToExtent($event)" (onSelectLayer)="handleSelectOverlayLayer($event)"></fm-map-layer-list>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
<li class="nav-item py-0">
|
||||
<span><i class="fal fa-layer-group" aria-hidden="true"></i> <span i18n>Aerial photos</span></span>
|
||||
<div class="mb-4">
|
||||
<fm-map-layer-list [baseLayers]="true" [itemLayers]="aerialMaps|async" [selectedLayer]="selectedBaseLayer|async" (onSelectLayer)="handleSelectBaseLayer($event)"></fm-map-layer-list>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,12 +4,13 @@ import { Store } from '@ngrx/store';
|
||||
import * as mapReducers from '../../reducers/map.reducer';
|
||||
import * as mapActions from '../../actions/map.actions';
|
||||
import {createEmpty,extend } from 'ol/extent';
|
||||
import { Observable } from 'rxjs';
|
||||
import { filter, map, Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-layer-switcher',
|
||||
templateUrl: './layer-switcher.component.html',
|
||||
styleUrls: ['./layer-switcher.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-layer-switcher',
|
||||
templateUrl: './layer-switcher.component.html',
|
||||
styleUrls: ['./layer-switcher.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class LayerSwitcher implements OnInit,OnChanges{
|
||||
|
||||
@@ -17,7 +18,8 @@ export class LayerSwitcher implements OnInit,OnChanges{
|
||||
public overlayLayers: Observable<Array<IItemLayer>>;
|
||||
public selectedOverlayLayer: Observable<IItemLayer>;
|
||||
public selectedItemLayer$: Observable<IItemLayer>;
|
||||
public baseLayers: Observable<Array<IItemLayer>>;
|
||||
public baseMaps: Observable<Array<IItemLayer>>;
|
||||
public aerialMaps: Observable<Array<IItemLayer>>;
|
||||
public selectedBaseLayer: Observable<IItemLayer>;
|
||||
|
||||
constructor( private store: Store<mapReducers.State>) {
|
||||
@@ -26,7 +28,8 @@ export class LayerSwitcher implements OnInit,OnChanges{
|
||||
ngOnInit() {
|
||||
this.overlayLayers = this.store.select(mapReducers.selectGetOverlayLayers);
|
||||
this.selectedOverlayLayer = this.store.select(mapReducers.selectGetSelectedOverlayLayer);
|
||||
this.baseLayers = this.store.select(mapReducers.selectGetBaseLayers);
|
||||
this.baseMaps = this.store.select(mapReducers.selectGetBaseMaps);
|
||||
this.aerialMaps = this.store.select(mapReducers.selectGetArealMaps);
|
||||
this.selectedBaseLayer = this.store.select(mapReducers.selectGetSelectedBaseLayer);
|
||||
this.selectedItemLayer$ = this.store.select(mapReducers.selectGetSelectedItemLayer)
|
||||
this.showLayerSwitcher = this.store.select(mapReducers.selectGetShowLayerSwitcher);
|
||||
@@ -83,3 +86,4 @@ export class LayerSwitcher implements OnInit,OnChanges{
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
<div class="col-8 nopadding" ><span i18n>Max</span>:</div>
|
||||
<div class="col-4 pull-left nopadding">{{ getScaledValue(histogram.max)| number:'1.0-2'}}</div>
|
||||
|
||||
<ng-container *ngIf="showConfidenceInterval()">
|
||||
@if (showConfidenceInterval()) {
|
||||
<div class="col-8 nopadding"><span i18n>Confidence interval</span>:</div>
|
||||
<div class="col-4 pull-left nopadding">{{ getScaledValue(histogram.confidence * 100)| number:'1.0-0'}}%</div>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -2,12 +2,13 @@ import {Component, Input} from '@angular/core';
|
||||
import {IHistogram, ILayer} from '../../../models/color.map';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-histogram-details',
|
||||
templateUrl: './histogram-details.component.html',
|
||||
styles: ['.nopadding{\n' +
|
||||
' padding: 0 !important;\n' +
|
||||
' margin: 0 !important;\n' +
|
||||
'}']
|
||||
selector: 'fm-map-histogram-details',
|
||||
templateUrl: './histogram-details.component.html',
|
||||
styles: ['.nopadding{\n' +
|
||||
' padding: 0 !important;\n' +
|
||||
' margin: 0 !important;\n' +
|
||||
'}'],
|
||||
standalone: false
|
||||
})
|
||||
export class HistogramDetailsComponent {
|
||||
|
||||
|
||||
@@ -1,48 +1,68 @@
|
||||
<table class="container" *ngIf="showLegend()">
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<div class="title">
|
||||
<h4 *ngIf="showTitle">{{layer.name}}</h4>
|
||||
<b *ngIf="layer.unit">({{layer.unit}})</b>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a i18n-title title="more info"><i class="fal fa-info-circle text-primary" (click)="hideHistogramDetails = !hideHistogramDetails"></i></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<div class="title" *ngIf="histogramenabled">
|
||||
<h4>{{histogram}}</h4>
|
||||
<b *ngIf="histogramunit">({{histogramunit}})</b>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr *ngFor="let entry of layer.renderer.colorMap.entries; let i = index ">
|
||||
<td class="legend-items"><span [style.background-color]="getAlphaHex(entry.color)" [style.border-color]="getHex(entry.color)"class="color"></span></td>
|
||||
<td class="legend-items-text"><span *ngIf="!entry.label">{{getScaledValue(entry.value,layer.scale) | number:'1.0-2'}} {{legendunit}}</span><span *ngIf="entry.label">{{entry.label}}</span></td>
|
||||
<td class="histogram-items">
|
||||
<div *ngIf="showHistogram()">
|
||||
<span class="bar" [style.background-color]="getHex(entry.color)" [style.width]="getPart(layer.renderer, i)">
|
||||
</span>
|
||||
<span *ngIf="getPercentage(layer.renderer,i) as percentage" class="bar-label">{{percentage | number:'1.0-2'}} %</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr *ngIf="showHistogram()">
|
||||
<td colspan="4" class="pb-1 pt-1">
|
||||
<div class="info" [ngbCollapse]="hideHistogramDetails">
|
||||
<ng-container *ngIf="bandContainsStatistics(); else histogram">
|
||||
<fm-map-statistics-details [statistics]="layer.renderer.band.statistics" [scale]="layer.scale"></fm-map-statistics-details>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #histogram>
|
||||
<fm-map-histogram-details [histogram]="layer.renderer.band.histogram" [scale]="layer.scale"></fm-map-histogram-details>
|
||||
</ng-template>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@if (showLegend()) {
|
||||
<table class="container">
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<div class="title">
|
||||
@if (showTitle) {
|
||||
<h4>{{layer.name}}</h4>
|
||||
}
|
||||
@if (layer.unit) {
|
||||
<b>({{layer.unit}})</b>
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a i18n-title title="more info"><i class="fal fa-info-circle text-primary" (click)="hideHistogramDetails = !hideHistogramDetails"></i></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
@if (histogramenabled) {
|
||||
<div class="title">
|
||||
<h4>{{histogram}}</h4>
|
||||
@if (histogramunit) {
|
||||
<b>({{histogramunit}})</b>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
@for (entry of layer.renderer.colorMap.entries; track $index; let i = $index) {
|
||||
<tr>
|
||||
<td class="legend-items"><span [style.background-color]="getAlphaHex(entry.color)" [style.border-color]="getHex(entry.color)"class="color"></span></td>
|
||||
<td class="legend-items-text">@if (!entry.label) {
|
||||
<span>{{getScaledValue(entry.value,layer.scale) | number:'1.0-2'}} {{legendunit}}</span>
|
||||
}@if (entry.label) {
|
||||
<span>{{entry.label}}</span>
|
||||
}</td>
|
||||
<td class="histogram-items">
|
||||
@if (showHistogram()) {
|
||||
<div>
|
||||
<span class="bar" [style.background-color]="getHex(entry.color)" [style.width]="getPart(layer.renderer, i)">
|
||||
</span>
|
||||
@if (getPercentage(layer.renderer,i); as percentage) {
|
||||
<span class="bar-label">{{percentage | number:'1.0-2'}} %</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (showHistogram()) {
|
||||
<tr>
|
||||
<td colspan="4" class="pb-1 pt-1">
|
||||
<div class="info" [ngbCollapse]="hideHistogramDetails">
|
||||
@if (bandContainsStatistics()) {
|
||||
<fm-map-statistics-details [statistics]="layer.renderer.band.statistics" [scale]="layer.scale"></fm-map-statistics-details>
|
||||
} @else {
|
||||
<fm-map-histogram-details [histogram]="layer.renderer.band.histogram" [scale]="layer.scale"></fm-map-histogram-details>
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,10 +2,11 @@ import { Component, OnInit, Input,AfterViewInit } from '@angular/core';
|
||||
import { IColorMap, IColor, IColorEntry,ILayer, IRenderer } from '../../models/color.map';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-layer-legend',
|
||||
templateUrl: './legend.component.html',
|
||||
styleUrls: ['./legend.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-layer-legend',
|
||||
templateUrl: './legend.component.html',
|
||||
styleUrls: ['./legend.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class LegendComponent implements OnInit,AfterViewInit {
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
<div class="col-4 pull-left nopadding">{{getSquaredScaledValue(statistics.variance)| number:'1.0-2'}}</div>
|
||||
<div class="col-8 nopadding"><span i18n>Coefficient of variation</span>:</div>
|
||||
<div class="col-4 pull-left nopadding">{{statistics.variationCoefficient | number:'1.0-2'}}</div>
|
||||
<ng-container *ngIf="statistics.confidenceIntervalLow !== undefined">
|
||||
@if (statistics.confidenceIntervalLow !== undefined) {
|
||||
<div class="col-8 nopadding">90% <span i18n>Confidence interval</span>:</div>
|
||||
<div class="col-4 pull-left nopadding">{{getScaledValue(statistics.confidenceIntervalLow) | number:'1.0-2'}} - {{getScaledValue(statistics.confidenceIntervalHigh) | number:'1.0-2'}}</div>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -2,12 +2,13 @@ import { Component, Input } from '@angular/core';
|
||||
import { IStatistics } from '../../../models/color.map';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-statistics-details',
|
||||
templateUrl: './statistics-details.component.html',
|
||||
styles: ['.nopadding{\n' +
|
||||
' padding: 0 !important;\n' +
|
||||
' margin: 0 !important;\n' +
|
||||
'}']
|
||||
selector: 'fm-map-statistics-details',
|
||||
templateUrl: './statistics-details.component.html',
|
||||
styles: ['.nopadding{\n' +
|
||||
' padding: 0 !important;\n' +
|
||||
' margin: 0 !important;\n' +
|
||||
'}'],
|
||||
standalone: false
|
||||
})
|
||||
export class StatisticsDetailsComponent {
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ div.map-search {
|
||||
}
|
||||
|
||||
.disabled {
|
||||
color:lighten(#000000,80%);
|
||||
color:adjust(#000000,80%);
|
||||
}
|
||||
|
||||
:host ::ng-deep ngb-typeahead-window.dropdown-menu {
|
||||
|
||||
@@ -6,10 +6,11 @@ import { IQueryState } from '@farmmaps/common';
|
||||
import { IPeriodState } from '../../models/period.state';
|
||||
import { tassign } from 'tassign';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-map-search',
|
||||
templateUrl: './map-search.component.html',
|
||||
styleUrls: ['./map-search.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-map-search',
|
||||
templateUrl: './map-search.component.html',
|
||||
styleUrls: ['./map-search.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class MapSearchComponent {
|
||||
|
||||
|
||||
@@ -1,95 +1,109 @@
|
||||
<ng-container *ngIf="{
|
||||
mapState:mapState$|async,
|
||||
extent:extent$|async,
|
||||
baseLayers:baseLayers$|async,
|
||||
overlayLayers:overlayLayers$|async,
|
||||
selectedItemLayer:selectedItemLayer$|async,
|
||||
features:features$|async,
|
||||
position:position$|async,
|
||||
parentCode:parentCode$|async,
|
||||
panelVisible:panelVisible$|async,
|
||||
openedModalName:openedModalName$|async,
|
||||
panelCollapsed:panelCollapsed$|async,
|
||||
panelExtraWide:panelExtraWide$|async,
|
||||
searchMinified:searchMinified$|async,
|
||||
selectedItem:selectedItem$|async,
|
||||
parentItem:parentItem$|async,
|
||||
queryState:queryState$|async,
|
||||
searchCollapsed:searchCollapsed$|async,
|
||||
clearEnabled:clearEnabled$|async,
|
||||
period:period$|async,
|
||||
compassHeading:compassHeading$|async,
|
||||
styles:styles$|async,
|
||||
selectedFeature:selectedFeature$|async,
|
||||
fullscreen:fullscreen$|async,
|
||||
showDataLayerSlide:showDataLayerSlide$|async
|
||||
} as state">
|
||||
<aol-map #map (moveEnd)="handleOnMoveEnd($event)" (click)="handleOnMouseDown($event)" (dblClick)="handleShowLayerValues($event)" [ngClass]="{'panel-visible':state.panelVisible,'fullscreen':state.fullscreen }" class="map">
|
||||
<div>
|
||||
|
||||
</div>
|
||||
|
||||
<aol-view [zoom]="state.mapState.zoom" [rotation]="state.mapState.rotation">
|
||||
<aol-coordinate [x]="state.mapState.xCenter" [y]="state.mapState.yCenter" [srid]="'EPSG:4326'"></aol-coordinate>
|
||||
<fm-map-zoom-to-extent [extent]="state.extent" [animate]="true"></fm-map-zoom-to-extent>
|
||||
</aol-view>
|
||||
|
||||
<aol-interaction-default></aol-interaction-default>
|
||||
<aol-interaction-dragrotateandzoom></aol-interaction-dragrotateandzoom>
|
||||
<fm-map-item-layers [itemLayers]="state.baseLayers"></fm-map-item-layers>
|
||||
<fm-map-item-layers *ngIf="!overrideOverlayLayers" [itemLayers]="state.overlayLayers"></fm-map-item-layers>
|
||||
<fm-map-item-layers *ngIf="!overrideSelectedItemLayer" [itemLayer]="state.selectedItemLayer" (onPrerender)="handlePrerender($event)"></fm-map-item-layers>
|
||||
<aol-layer-vector>
|
||||
<fm-map-item-source-vector [styles]="state.styles" [features]="state.features" (onFeatureSelected)="handleFeatureClick($event)" (onFeatureHover)="handleFeatureHover($event)" [selectedFeature]="state.selectedFeature" [selectedItem]="state.selectedItem"></fm-map-item-source-vector>
|
||||
</aol-layer-vector>
|
||||
<router-outlet name="map-layers"></router-outlet>
|
||||
<fm-map-gps-location [position]="state.position" [headingTolerance]="20" [showHeading]="devicesService.IsMobile()" [showTolerance]="devicesService.IsMobile()" [heading]="state.compassHeading"></fm-map-gps-location>
|
||||
<fm-map-layer-values></fm-map-layer-values>
|
||||
<div class="viewport-container" [ngStyle]="{'bottom': bottom(state.panelVisible)}">
|
||||
<div class="control-container">
|
||||
<router-outlet name="map-controls"></router-outlet>
|
||||
<fm-map-layer-switcher></fm-map-layer-switcher>
|
||||
<fm-map-pan-to-location [position]="state.position" [mapState]="state.mapState" [animate]="true"></fm-map-pan-to-location>
|
||||
<fm-map-rotation-reset></fm-map-rotation-reset>
|
||||
</div>
|
||||
<div class="slide-container" [ngClass]="{'showDataLayerSlide':state.showDataLayerSlide}">
|
||||
<form>
|
||||
<input class="dataLayerSlide" (input)="handleSlideChange($event)" type="range" style="width: 100%" value="{{dataLayerSlideValue}}"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<fm-map-file-drop-target [parentCode]="state.parentCode" (onFileDropped)="handleFileDropped($event)"></fm-map-file-drop-target>
|
||||
|
||||
<div *ngIf="noContent">
|
||||
<fm-map-map-search #mapSearch [openedModalName]="state.openedModalName" (onOpenModal)="handleOpenModal($event)" (onCloseModal)="handleCloseModal()" [ngClass]="{'menuVisible':state.menuVisible}" (onToggleMenu)="handleToggleMenu($event)" (onSearchCollapse)="handleSearchCollapse($event)" (onSearchExpand)="handleSearchExpand($event)" [collapsed]="state.searchCollapsed" [searchMinified]="state.searchMinified" (onSearch)="handleSearch($event)" (onClear)="handleClearSearch($event)" [filterOptions]="state.queryState" [clearEnabled]="state.clearEnabled" [period]="state.period" (onPeriodChange)="handlePeriodChange($event)" (onCitySearch)="handleCitySearch($event)"></fm-map-map-search>
|
||||
</div>
|
||||
<div class="side-panel-container">
|
||||
|
||||
<fm-side-panel [resizeable]="true" (onResize)="handlePanelResize($event)" [visible]="state.panelVisible && noContent" [collapsed]="state.panelCollapsed" [collapsable]="false" [extrawide]="state.panelExtraWide">
|
||||
<div class="panel-wrapper" *ngIf="noContent">
|
||||
<div class="panel-top bg-secondary" *ngIf="!(state.searchMinified)">
|
||||
</div>
|
||||
<div class="panel-bottom">
|
||||
|
||||
<div *ngIf="!(state.selectedItem)">
|
||||
<fm-map-feature-list-container [features]="state.features" [selectedFeature]="state.selectedFeature" [queryState]="state.queryState" [clickedFeature]="clickedFeature"></fm-map-feature-list-container>
|
||||
</div>
|
||||
|
||||
<div *ngIf="state.selectedItem;let item">
|
||||
<fm-map-selected-item-container [item]="item" [parentItem]="state.parentItem" [itemLayer]="state.selectedItemLayer" [overlayLayers]="state.overlayLayers"></fm-map-selected-item-container>
|
||||
</div>
|
||||
<div *ngIf="state.features.length == 0" class="no-results m-2">
|
||||
<div *ngIf="state.queryState.query">Cannot find <span>{{state.queryState?.query}}</span></div>
|
||||
<div *ngIf="state.queryState?.tags">Cannot find tag <span>{{state.queryState?.tags}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fm-side-panel>
|
||||
<fm-side-panel [resizeable]="true" [visible]="!noContent" [extrawide]="state.panelExtraWide">
|
||||
<router-outlet (activate)="handleSidepaneloutletActivate($event)" (deactivate)="handleSidepaneloutletDeactivate($event)"></router-outlet>
|
||||
</fm-side-panel>
|
||||
</div>
|
||||
</aol-map>
|
||||
</ng-container>
|
||||
|
||||
|
||||
@if ({
|
||||
mapState:mapState$|async,
|
||||
extent:extent$|async,
|
||||
baseLayers:baseLayers$|async,
|
||||
overlayLayers:overlayLayers$|async,
|
||||
selectedItemLayer:selectedItemLayer$|async,
|
||||
features:features$|async,
|
||||
position:position$|async,
|
||||
parentCode:parentCode$|async,
|
||||
panelVisible:panelVisible$|async,
|
||||
openedModalName:openedModalName$|async,
|
||||
panelCollapsed:panelCollapsed$|async,
|
||||
panelExtraWide:panelExtraWide$|async,
|
||||
searchMinified:searchMinified$|async,
|
||||
selectedItem:selectedItem$|async,
|
||||
parentItem:parentItem$|async,
|
||||
queryState:queryState$|async,
|
||||
searchCollapsed:searchCollapsed$|async,
|
||||
clearEnabled:clearEnabled$|async,
|
||||
period:period$|async,
|
||||
compassHeading:compassHeading$|async,
|
||||
styles:styles$|async,
|
||||
selectedFeature:selectedFeature$|async,
|
||||
fullscreen:fullscreen$|async,
|
||||
showDataLayerSlide:showDataLayerSlide$|async,
|
||||
menuVisible:menuVisible$|async,
|
||||
}; as state) {
|
||||
<aol-map #map (moveEnd)="handleOnMoveEnd($event)" (click)="handleOnMouseDown($event)" (dblClick)="handleShowLayerValues($event)" [ngClass]="{'panel-visible':state.panelVisible,'fullscreen':state.fullscreen }" class="map">
|
||||
<div>
|
||||
</div>
|
||||
<aol-view [zoom]="state.mapState.zoom" [rotation]="state.mapState.rotation">
|
||||
<aol-coordinate [x]="state.mapState.xCenter" [y]="state.mapState.yCenter" [srid]="'EPSG:4326'"></aol-coordinate>
|
||||
<fm-map-zoom-to-extent [extent]="state.extent" [animate]="true"></fm-map-zoom-to-extent>
|
||||
</aol-view>
|
||||
<aol-interaction-default></aol-interaction-default>
|
||||
<aol-interaction-dragrotateandzoom></aol-interaction-dragrotateandzoom>
|
||||
<fm-map-item-layers [itemLayers]="state.baseLayers"></fm-map-item-layers>
|
||||
@if (!overrideOverlayLayers) {
|
||||
<fm-map-item-layers [itemLayers]="state.overlayLayers"></fm-map-item-layers>
|
||||
}
|
||||
@if (!overrideSelectedItemLayer) {
|
||||
<fm-map-item-layers [itemLayer]="state.selectedItemLayer" (onPrerender)="handlePrerender($event)"></fm-map-item-layers>
|
||||
}
|
||||
<aol-layer-vector>
|
||||
<fm-map-item-source-vector [styles]="state.styles" [features]="state.features" (onFeatureSelected)="handleFeatureClick($event)" (onFeatureHover)="handleFeatureHover($event)" [selectedFeature]="state.selectedFeature" [selectedItem]="state.selectedItem"></fm-map-item-source-vector>
|
||||
</aol-layer-vector>
|
||||
<router-outlet name="map-layers"></router-outlet>
|
||||
<fm-map-gps-location [position]="state.position" [headingTolerance]="20" [showHeading]="devicesService.IsMobile()" [showTolerance]="devicesService.IsMobile()" [heading]="state.compassHeading"></fm-map-gps-location>
|
||||
<fm-map-layer-values></fm-map-layer-values>
|
||||
<div class="viewport-container" [ngStyle]="{'bottom': bottom(state.panelVisible)}">
|
||||
<div class="control-container">
|
||||
<router-outlet name="map-controls"></router-outlet>
|
||||
<fm-map-layer-switcher></fm-map-layer-switcher>
|
||||
<fm-map-pan-to-location [position]="state.position" [mapState]="state.mapState" [animate]="true"></fm-map-pan-to-location>
|
||||
<fm-map-rotation-reset></fm-map-rotation-reset>
|
||||
</div>
|
||||
<div class="slide-container" [ngClass]="{'showDataLayerSlide':state.showDataLayerSlide}">
|
||||
<form>
|
||||
<input class="dataLayerSlide" (input)="handleSlideChange($event)" type="range" style="width: 100%" value="{{dataLayerSlideValue}}"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<fm-map-file-drop-target [parentCode]="state.parentCode" (onFileDropped)="handleFileDropped($event)"></fm-map-file-drop-target>
|
||||
@if (noContent) {
|
||||
<div>
|
||||
<fm-map-map-search #mapSearch [openedModalName]="state.openedModalName" (onOpenModal)="handleOpenModal($event)" (onCloseModal)="handleCloseModal()" [ngClass]="{'menuVisible':state.menuVisible}" (onToggleMenu)="handleToggleMenu($event)" (onSearchCollapse)="handleSearchCollapse($event)" (onSearchExpand)="handleSearchExpand($event)" [collapsed]="state.searchCollapsed" [searchMinified]="state.searchMinified" (onSearch)="handleSearch($event)" (onClear)="handleClearSearch($event)" [filterOptions]="state.queryState" [clearEnabled]="state.clearEnabled" [period]="state.period" (onPeriodChange)="handlePeriodChange($event)" (onCitySearch)="handleCitySearch($event)"></fm-map-map-search>
|
||||
</div>
|
||||
}
|
||||
<div class="side-panel-container">
|
||||
<fm-side-panel [resizeable]="true" (onResize)="handlePanelResize($event)" [visible]="state.panelVisible && noContent" [collapsed]="state.panelCollapsed" [collapsable]="false" [extrawide]="state.panelExtraWide">
|
||||
@if (noContent) {
|
||||
<div class="panel-wrapper">
|
||||
@if (!(state.searchMinified)) {
|
||||
<div class="panel-top bg-secondary">
|
||||
</div>
|
||||
}
|
||||
<div class="panel-bottom">
|
||||
@if (!(state.selectedItem)) {
|
||||
<div>
|
||||
<fm-map-feature-list-container [features]="state.features" [selectedFeature]="state.selectedFeature" [queryState]="state.queryState" [clickedFeature]="clickedFeature"></fm-map-feature-list-container>
|
||||
</div>
|
||||
}
|
||||
@if (state.selectedItem; as item) {
|
||||
<div>
|
||||
<fm-map-selected-item-container [item]="item" [parentItem]="state.parentItem" [itemLayer]="state.selectedItemLayer" [overlayLayers]="state.overlayLayers"></fm-map-selected-item-container>
|
||||
</div>
|
||||
}
|
||||
@if (state.features.length == 0) {
|
||||
<div class="no-results m-2">
|
||||
@if (state.queryState.query) {
|
||||
<div>Cannot find <span>{{state.queryState?.query}}</span></div>
|
||||
}
|
||||
@if (state.queryState?.tags) {
|
||||
<div>Cannot find tag <span>{{state.queryState?.tags}}</span></div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</fm-side-panel>
|
||||
<fm-side-panel [resizeable]="true" [visible]="!noContent" [extrawide]="state.panelExtraWide">
|
||||
<router-outlet (activate)="handleSidepaneloutletActivate($event)" (deactivate)="handleSidepaneloutletDeactivate($event)"></router-outlet>
|
||||
</fm-side-panel>
|
||||
</div>
|
||||
</aol-map>
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,11 +52,20 @@ aol-map { position:absolute;width:100%;height:calc( 100vh );}
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.control-container {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
|
||||
.control-container {
|
||||
float:right;
|
||||
margin-right: 1em;
|
||||
pointer-events: all;
|
||||
@media screen and (min-width: 768px) {
|
||||
.control-container {
|
||||
float: right;
|
||||
margin-right: 1em;
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
|
||||
.fullscreen .viewport-container {
|
||||
|
||||
@@ -1,50 +1,51 @@
|
||||
import { Component, OnInit, OnDestroy, HostListener, ViewChild, AfterViewInit,NgZone,ElementRef } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy, HostListener, ViewChild, AfterViewInit, NgZone, ElementRef } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { Observable, Subject, Subscription, from,of ,EMPTY } from 'rxjs';
|
||||
import { withLatestFrom, switchMap,skip } from 'rxjs/operators';
|
||||
import { Observable, Subject, Subscription, from, of, EMPTY } from 'rxjs';
|
||||
import { withLatestFrom, switchMap, skip } from 'rxjs/operators';
|
||||
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { DeviceService } from '@farmmaps/common';
|
||||
import {getRenderPixel} from 'ol/render';
|
||||
import { getRenderPixel } from 'ol/render';
|
||||
|
||||
// Map
|
||||
import * as mapReducers from '../../reducers/map.reducer';
|
||||
import * as mapActions from '../../actions/map.actions';
|
||||
import { IMapState} from '../../models/map.state';
|
||||
import { IClickedFeature} from '../../models/clicked.feature';
|
||||
import { IMapState } from '../../models/map.state';
|
||||
import { IClickedFeature } from '../../models/clicked.feature';
|
||||
import { IQuery } from '../../reducers/map.reducer'
|
||||
import { ISelectedFeatures } from '../../models/selected.features';
|
||||
import { IItemLayer } from '../../models/item.layer';
|
||||
import { IListItem, IQueryState } from '@farmmaps/common';
|
||||
import { IPeriodState } from '../../models/period.state';
|
||||
import {IStyles} from '../../models/style.cache';
|
||||
import { IStyles } from '../../models/style.cache';
|
||||
import { IDroppedFile } from '../aol/file-drop-target/file-drop-target.component';
|
||||
import { StateSerializerService } from '@farmmaps/common';
|
||||
import { GeolocationService} from '../../services/geolocation.service';
|
||||
import { GeolocationService } from '../../services/geolocation.service';
|
||||
import { GeolocatorService } from '@farmmaps/common';
|
||||
import {DeviceOrientationService} from '../../services/device-orientation.service';
|
||||
import { DeviceOrientationService } from '../../services/device-orientation.service';
|
||||
|
||||
// AppCommon
|
||||
import { ResumableFileUploadService, ItemTypeService } from '@farmmaps/common';
|
||||
import { IItemType, IItem } from '@farmmaps/common';
|
||||
import {commonReducers} from '@farmmaps/common';
|
||||
import {commonActions} from '@farmmaps/common';
|
||||
import { commonReducers } from '@farmmaps/common';
|
||||
import { commonActions } from '@farmmaps/common';
|
||||
|
||||
import {Feature} from 'ol';
|
||||
import {Geometry,Point,Circle} from 'ol/geom';
|
||||
import {Extent,createEmpty,extend } from 'ol/extent';
|
||||
import {transform} from 'ol/proj';
|
||||
import { Feature } from 'ol';
|
||||
import { Geometry, Point, Circle } from 'ol/geom';
|
||||
import { Extent, createEmpty, extend } from 'ol/extent';
|
||||
import { transform } from 'ol/proj';
|
||||
import { tassign } from 'tassign';
|
||||
import * as style from 'ol/style';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-map',
|
||||
templateUrl: './map.component.html',
|
||||
styleUrls: ['./map.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-map',
|
||||
templateUrl: './map.component.html',
|
||||
styleUrls: ['./map.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
|
||||
export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
export class MapComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
title = 'Map';
|
||||
public openedModalName$: Observable<string> = this.store.select(commonReducers.selectOpenedModalName);
|
||||
public itemTypes$: Observable<{ [id: string]: IItemType }>;
|
||||
@@ -54,49 +55,51 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
public selectedOverlayLayer$: Observable<IItemLayer> = this.store.select(mapReducers.selectGetSelectedOverlayLayer);
|
||||
public selectedItemLayer$: Observable<IItemLayer> = this.store.select(mapReducers.selectGetSelectedItemLayer);
|
||||
public baseLayers$: Observable<Array<IItemLayer>> = this.store.select(mapReducers.selectGetBaseLayers);
|
||||
public selectedBaseLayer$: Observable<IItemLayer> = this.store.select(mapReducers.selectGetSelectedBaseLayer);
|
||||
public selectedBaseLayer$: Observable<IItemLayer> = this.store.select(mapReducers.selectGetSelectedBaseLayer);
|
||||
public projection$: Observable<string> = this.store.select(mapReducers.selectGetProjection);
|
||||
public selectedFeatures$: Subject<ISelectedFeatures> = new Subject<ISelectedFeatures>();
|
||||
public droppedFile$: Subject<IDroppedFile> = new Subject<IDroppedFile>();
|
||||
public droppedFile$: Subject<IDroppedFile> = new Subject<IDroppedFile>();
|
||||
private paramSub: Subscription;
|
||||
private itemTypeSub: Subscription;
|
||||
private stateSub: Subscription;
|
||||
private queryStateSub: Subscription;
|
||||
private querySub: Subscription;
|
||||
public parentCode$: Observable<string> =this.store.select(mapReducers.selectGetParentCode);
|
||||
public parentCode$: Observable<string> = this.store.select(mapReducers.selectGetParentCode);
|
||||
public panelVisible$: Observable<boolean> = this.store.select(mapReducers.selectGetPanelVisible);
|
||||
public panelCollapsed$: Observable<boolean> = this.store.select(mapReducers.selectGetPanelCollapsed);
|
||||
public panelExtraWide$: Observable<boolean> = this.store.select(mapReducers.selectGetPanelExtraWide);
|
||||
public selectedFeature$: Observable<Feature<Geometry>> = this.store.select(mapReducers.selectGetSelectedFeature);
|
||||
public clickedFeature: Subject<Feature<Geometry>> = new Subject<Feature<Geometry>>();
|
||||
public selectedItem$: Observable<IItem> = this.store.select(mapReducers.selectGetSelectedItem);
|
||||
public parentItem$: Observable<IItem> =this.store.select(mapReducers.selectGetParentItem);
|
||||
public parentItem$: Observable<IItem> = this.store.select(mapReducers.selectGetParentItem);
|
||||
public queryState$: Observable<IQueryState> = this.store.select(mapReducers.selectGetQueryState);
|
||||
public state$:Observable<{mapState:IMapState,queryState:IQueryState}> = this.store.select(mapReducers.selectGetState);
|
||||
public state$: Observable<{ mapState: IMapState, queryState: IQueryState }> = this.store.select(mapReducers.selectGetState);
|
||||
public period$: Observable<IPeriodState> = this.store.select(mapReducers.selectGetPeriod);
|
||||
public clearEnabled$: Observable<boolean> = this.store.select(mapReducers.selectGetClearEnabled);
|
||||
public searchCollapsed$: Observable<boolean> = this.store.select(mapReducers.selectGetSearchCollapsed);
|
||||
public searchMinified$: Observable<boolean> = this.store.select(mapReducers.selectGetSearchMinified);
|
||||
public showDataLayerSlide$: Observable<boolean> = this.store.select(mapReducers.selectGetShowdataLayerSlide);
|
||||
public menuVisible$: Observable<boolean>;
|
||||
public query$: Observable<IQuery> = this.store.select(mapReducers.selectGetQuery);
|
||||
public query$: Observable<IQuery> = this.store.select(mapReducers.selectGetQuery);
|
||||
public position$: Observable<GeolocationPosition> = this.geolocationService.getCurrentPosition();
|
||||
public compassHeading$: Observable<number> = this.deviceorientationService.getCurrentCompassHeading();
|
||||
public baseLayersCollapsed = true;
|
||||
public overlayLayersCollapsed = true;
|
||||
public extent$: Observable<Extent> = this.store.select(mapReducers.selectGetExtent);
|
||||
public styles$:Observable<IStyles> = this.store.select(mapReducers.selectGetStyles);
|
||||
public styles$: Observable<IStyles> = this.store.select(mapReducers.selectGetStyles);
|
||||
public fullscreen$: Observable<boolean> = this.store.select(commonReducers.selectGetFullScreen);
|
||||
private lastUrl = "";
|
||||
private initialized = false;
|
||||
public noContent = false;
|
||||
public overrideSelectedItemLayer = false;
|
||||
public overrideOverlayLayers = false;
|
||||
public hideShowLayerValues = false;
|
||||
public const
|
||||
public dataLayerSlideValue = 50;
|
||||
public dataLayerSlideEnabled = false;
|
||||
private visibleAreaBottom = 0;
|
||||
private viewEnabled = true;
|
||||
|
||||
|
||||
@ViewChild('map') map;
|
||||
@ViewChild('contentDiv') contentDiv: ElementRef;
|
||||
|
||||
@@ -110,47 +113,48 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
private geolocationService: GeolocationService,
|
||||
private geolocaterService: GeolocatorService,
|
||||
private zone: NgZone,
|
||||
private deviceorientationService:DeviceOrientationService,
|
||||
public devicesService:DeviceService) {
|
||||
if(route && route.snapshot && route.snapshot.data && route.snapshot.data["fm-map-map"]) {
|
||||
const params = route.snapshot.data["fm-map-map"];
|
||||
this.overrideSelectedItemLayer = params["overrideSelectedItemlayer"] ? params["overrideSelectedItemlayer"] : false;
|
||||
this.overrideOverlayLayers = params["overrideOverlayLayers"] ? params["overrideOverlayLayers"] : false;
|
||||
}
|
||||
this.querySub = this.query$.pipe(skip(1), withLatestFrom(this.mapState$)).subscribe(([query,mapState]) =>{
|
||||
if(query && query.querystate) {
|
||||
let newQueryState = tassign(mapReducers.initialQueryState);
|
||||
//console.debug(`Do Query`);
|
||||
const urlparts=[];
|
||||
if (query.querystate.itemCode && query.querystate.itemCode != "") {
|
||||
if(query.querystate.itemType && query.querystate.itemType!= "") {
|
||||
const itemType = this.itemTypeService.itemTypes[query.querystate.itemType];
|
||||
if (itemType && itemType.viewer && itemType.viewer == "edit_in_editor" && itemType.editor) {
|
||||
urlparts.push('/editor');
|
||||
urlparts.push(itemType.editor);
|
||||
urlparts.push('item');
|
||||
urlparts.push(query.querystate.itemCode);
|
||||
}
|
||||
private deviceorientationService: DeviceOrientationService,
|
||||
public devicesService: DeviceService) {
|
||||
if (route && route.snapshot && route.snapshot.data && route.snapshot.data["fm-map-map"]) {
|
||||
const params = route.snapshot.data["fm-map-map"];
|
||||
this.overrideSelectedItemLayer = params["overrideSelectedItemlayer"] ? params["overrideSelectedItemlayer"] : false;
|
||||
this.overrideOverlayLayers = params["overrideOverlayLayers"] ? params["overrideOverlayLayers"] : false;
|
||||
this.hideShowLayerValues = params["hideShowLayerValues"] ? params["hideShowLayerValues"] : false;
|
||||
}
|
||||
this.querySub = this.query$.pipe(skip(1), withLatestFrom(this.mapState$)).subscribe(([query, mapState]) => {
|
||||
if (query && query.querystate) {
|
||||
let newQueryState = tassign(mapReducers.initialQueryState);
|
||||
//console.debug(`Do Query`);
|
||||
const urlparts = [];
|
||||
if (query.querystate.itemCode && query.querystate.itemCode != "") {
|
||||
if (query.querystate.itemType && query.querystate.itemType != "") {
|
||||
const itemType = this.itemTypeService.itemTypes[query.querystate.itemType];
|
||||
if (itemType && itemType.viewer && itemType.viewer == "edit_in_editor" && itemType.editor) {
|
||||
urlparts.push('/editor');
|
||||
urlparts.push(itemType.editor);
|
||||
urlparts.push('item');
|
||||
urlparts.push(query.querystate.itemCode);
|
||||
}
|
||||
} else {
|
||||
newQueryState= query.querystate;
|
||||
}
|
||||
if(urlparts.length==0 ) {
|
||||
newQueryState.itemCode = query.querystate.itemCode;
|
||||
this.zone.run(() => {
|
||||
this.replaceUrl(mapState,newQueryState,query.replace);
|
||||
})
|
||||
} else {
|
||||
this.router.navigate(urlparts);
|
||||
}
|
||||
} else {
|
||||
newQueryState = query.querystate;
|
||||
}
|
||||
});
|
||||
this.store.dispatch(new mapActions.Init());
|
||||
// this.store.select(commonReducers.getRootItems).subscribe((l) => {
|
||||
// if(l && l.length>0) {
|
||||
// this.store.dispatch(new mapActions.Init());
|
||||
// }
|
||||
// });
|
||||
if (urlparts.length == 0) {
|
||||
newQueryState.itemCode = query.querystate.itemCode;
|
||||
this.zone.run(() => {
|
||||
this.replaceUrl(mapState, newQueryState, query.replace);
|
||||
})
|
||||
} else {
|
||||
this.router.navigate(urlparts);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.store.dispatch(new mapActions.Init());
|
||||
// this.store.select(commonReducers.getRootItems).subscribe((l) => {
|
||||
// if(l && l.length>0) {
|
||||
// this.store.dispatch(new mapActions.Init());
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
@HostListener('document:keyup', ['$event'])
|
||||
@@ -161,27 +165,27 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
handlePanelResize(resizeTop:number) {
|
||||
if(resizeTop==100 || !this.devicesService.IsMobile() ) {
|
||||
this.visibleAreaBottom=0;
|
||||
handlePanelResize(resizeTop: number) {
|
||||
if (resizeTop == 100 || !this.devicesService.IsMobile()) {
|
||||
this.visibleAreaBottom = 0;
|
||||
} else {
|
||||
this.visibleAreaBottom=100-resizeTop;
|
||||
if(this.visibleAreaBottom>60) {
|
||||
this.visibleAreaBottom=60;
|
||||
this.visibleAreaBottom = 100 - resizeTop;
|
||||
if (this.visibleAreaBottom > 60) {
|
||||
this.visibleAreaBottom = 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bottom(panelVisible:boolean) {
|
||||
if(panelVisible) {
|
||||
return this.visibleAreaBottom + '%';
|
||||
bottom(panelVisible: boolean) {
|
||||
if (panelVisible) {
|
||||
return this.visibleAreaBottom + '%';
|
||||
} else {
|
||||
return "0%";
|
||||
}
|
||||
}
|
||||
|
||||
handleOpenModal(modalName: string) {
|
||||
this.store.dispatch(new commonActions.OpenModal(modalName));
|
||||
this.store.dispatch(new commonActions.OpenModal(modalName));
|
||||
}
|
||||
|
||||
handleCloseModal() {
|
||||
@@ -189,7 +193,7 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
}
|
||||
|
||||
handleFileDropped(droppedFile: IDroppedFile) {
|
||||
this.uploadService.addFiles(droppedFile.files, droppedFile.event, { parentCode:droppedFile.parentCode, geometry:droppedFile.geometry });
|
||||
this.uploadService.addFiles(droppedFile.files, droppedFile.event, { parentCode: droppedFile.parentCode, geometry: droppedFile.geometry });
|
||||
}
|
||||
|
||||
handleFeatureClick(feature: Feature<Geometry>) {
|
||||
@@ -205,26 +209,26 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
this.store.dispatch(new mapActions.DoQuery(queryState));
|
||||
}
|
||||
|
||||
handleSidepaneloutletActivate(component:any) {
|
||||
if(component && component.hasOwnProperty('clickedFeature')) {
|
||||
(component as IClickedFeature).clickedFeature = this.clickedFeature;
|
||||
}
|
||||
if(component && component.hasOwnProperty('extrawide')) {
|
||||
this.store.dispatch(new mapActions.SetPanelExtraWide(true));
|
||||
handleSidepaneloutletActivate(component: any) {
|
||||
if (component && component.hasOwnProperty('clickedFeature')) {
|
||||
(component as IClickedFeature).clickedFeature = this.clickedFeature;
|
||||
}
|
||||
if (component && component.hasOwnProperty('extrawide')) {
|
||||
this.store.dispatch(new mapActions.SetPanelExtraWide(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleSidepaneloutletDeactivate(component:any) {
|
||||
if(component && component.hasOwnProperty('clickedFeature')) {
|
||||
handleSidepaneloutletDeactivate(component: any) {
|
||||
if (component && component.hasOwnProperty('clickedFeature')) {
|
||||
(component as IClickedFeature).clickedFeature = null;
|
||||
}
|
||||
if(component && component.hasOwnProperty('extrawide')) {
|
||||
if (component && component.hasOwnProperty('extrawide')) {
|
||||
this.store.dispatch(new mapActions.SetPanelExtraWide(false));
|
||||
}
|
||||
}
|
||||
|
||||
handlePrerender(event:any) {
|
||||
if(!this.dataLayerSlideEnabled) return;
|
||||
handlePrerender(event: any) {
|
||||
if (!this.dataLayerSlideEnabled) return;
|
||||
const ctx = event.context;
|
||||
const mapSize = this.map.instance.getSize();
|
||||
const width = mapSize[0] * (this.dataLayerSlideValue / 100);
|
||||
@@ -243,72 +247,74 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
ctx.clip();
|
||||
}
|
||||
|
||||
handleSlideChange(event:any) {
|
||||
this.dataLayerSlideValue = event.target.value;
|
||||
this.map.instance.render();
|
||||
handleSlideChange(event: any) {
|
||||
this.dataLayerSlideValue = event.target.value;
|
||||
this.map.instance.render();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
ngOnInit() {
|
||||
this.initialized = false;
|
||||
//console.debug("Init");
|
||||
this.store.dispatch(new mapActions.Clear());
|
||||
this.selectedFeatures$.next({x:0,y:0,features:[]});
|
||||
this.selectedFeatures$.next({ x: 0, y: 0, features: [] });
|
||||
this.selectedFeatures$.next(null);
|
||||
}
|
||||
|
||||
initCustomStyles() {
|
||||
this.store.dispatch(new mapActions.SetStyle('vnd.farmmaps.itemtype.layer',new style.Style({
|
||||
this.store.dispatch(new mapActions.SetStyle('vnd.farmmaps.itemtype.layer', new style.Style({
|
||||
stroke: new style.Stroke({
|
||||
color: 'red',
|
||||
lineDash: [ 5,5],
|
||||
lineDash: [5, 5],
|
||||
width: 1
|
||||
}),
|
||||
geometry:(feature) =>feature.getGeometry()
|
||||
geometry: (feature) => feature.getGeometry()
|
||||
})));
|
||||
this.store.dispatch(new mapActions.SetStyle('vnd.farmmaps.itemtype.layer_selected',new style.Style({
|
||||
this.store.dispatch(new mapActions.SetStyle('vnd.farmmaps.itemtype.layer_selected', new style.Style({
|
||||
stroke: new style.Stroke({
|
||||
color: 'red',
|
||||
lineDash: [ 5,5],
|
||||
lineDash: [5, 5],
|
||||
width: 3
|
||||
}),
|
||||
geometry:(feature) =>feature.getGeometry()
|
||||
geometry: (feature) => feature.getGeometry()
|
||||
})));
|
||||
}
|
||||
|
||||
round(value:number,decimals:number):number {
|
||||
round(value: number, decimals: number): number {
|
||||
const d = Math.pow(10, decimals);
|
||||
return Math.round((value + Number.EPSILON)*d)/d;
|
||||
return Math.round((value + Number.EPSILON) * d) / d;
|
||||
}
|
||||
|
||||
getMapStateFromUrl(params:ParamMap):IMapState {
|
||||
getMapStateFromUrl(params: ParamMap): IMapState {
|
||||
const hasUrlmapState = params.has("xCenter") && params.has("yCenter");
|
||||
if (hasUrlmapState) {
|
||||
const xCenter = parseFloat(params.get("xCenter"));
|
||||
const yCenter = parseFloat(params.get("yCenter"));
|
||||
const zoom = parseFloat(params.get("zoom"));
|
||||
const rotation = parseFloat(params.get("rotation"));
|
||||
const baseLayer = params.get("baseLayer")?params.get("baseLayer"):"";
|
||||
const newMapState = {zoom: zoom, rotation: rotation, xCenter: xCenter, yCenter: yCenter, baseLayerCode: baseLayer };
|
||||
const baseLayer = params.get("baseLayer") ? params.get("baseLayer") : "";
|
||||
const newMapState = { zoom: zoom, rotation: rotation, xCenter: xCenter, yCenter: yCenter, baseLayerCode: baseLayer };
|
||||
return newMapState;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
normalizeMapState(mapState:IMapState):IMapState {
|
||||
if(!mapState) return null;
|
||||
return {zoom: this.round(mapState.zoom,0),
|
||||
rotation: this.round(mapState.rotation,2),
|
||||
xCenter: this.round(mapState.xCenter,5),
|
||||
yCenter: this.round(mapState.yCenter,5),
|
||||
baseLayerCode: mapState.baseLayerCode };
|
||||
normalizeMapState(mapState: IMapState): IMapState {
|
||||
if (!mapState) return null;
|
||||
return {
|
||||
zoom: this.round(mapState.zoom, 0),
|
||||
rotation: this.round(mapState.rotation, 2),
|
||||
xCenter: this.round(mapState.xCenter, 5),
|
||||
yCenter: this.round(mapState.yCenter, 5),
|
||||
baseLayerCode: mapState.baseLayerCode
|
||||
};
|
||||
}
|
||||
|
||||
serializeMapState(mapState:IMapState):string {
|
||||
serializeMapState(mapState: IMapState): string {
|
||||
return JSON.stringify(this.normalizeMapState(mapState));
|
||||
}
|
||||
|
||||
getQueryStateFromUrl(params:ParamMap):IQueryState {
|
||||
getQueryStateFromUrl(params: ParamMap): IQueryState {
|
||||
if (params.has("queryState")) {
|
||||
const queryState = params.get("queryState");
|
||||
let newQueryState = tassign(mapReducers.initialQueryState);
|
||||
@@ -323,65 +329,65 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
|
||||
ngAfterViewInit() {
|
||||
//console.debug("View init");
|
||||
this.noContent=true;
|
||||
this.noContent = true;
|
||||
this.route.children.forEach((entry) => {
|
||||
if(entry.outlet=="primary") {
|
||||
this.noContent=false;
|
||||
if (entry.outlet == "primary") {
|
||||
this.noContent = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.initCustomStyles();
|
||||
|
||||
// url to state
|
||||
|
||||
const urlMapState = this.getMapStateFromUrl(this.route.snapshot.paramMap);
|
||||
const urlQueryState = this.getQueryStateFromUrl(this.route.snapshot.paramMap);
|
||||
if(urlQueryState && urlMapState && this.noContent) {
|
||||
this.store.dispatch(new mapActions.SetState(urlMapState,urlQueryState));
|
||||
window.localStorage.setItem("FarmMapsCommonMap_mapState",this.serializeMapState(urlMapState));
|
||||
} else if(urlQueryState && this.noContent) {
|
||||
this.store.dispatch(new mapActions.SetQueryState(urlQueryState));
|
||||
} else {
|
||||
this.store.dispatch(new mapActions.SetReplaceUrl(true));
|
||||
}
|
||||
const urlMapState = this.getMapStateFromUrl(this.route.snapshot.paramMap);
|
||||
const urlQueryState = this.getQueryStateFromUrl(this.route.snapshot.paramMap);
|
||||
if (urlQueryState && urlMapState && this.noContent) {
|
||||
this.store.dispatch(new mapActions.SetState(urlMapState, urlQueryState));
|
||||
window.localStorage.setItem("FarmMapsCommonMap_mapState", this.serializeMapState(urlMapState));
|
||||
} else if (urlQueryState && this.noContent) {
|
||||
this.store.dispatch(new mapActions.SetQueryState(urlQueryState));
|
||||
} else {
|
||||
this.store.dispatch(new mapActions.SetReplaceUrl(true));
|
||||
}
|
||||
|
||||
this.paramSub = this.route.paramMap.pipe(withLatestFrom(this.state$),switchMap(([params,state]) => {
|
||||
if(this.initialized && this.noContent) {
|
||||
const urlQueryState = this.getQueryStateFromUrl(params);
|
||||
if( this.serializeService.serialize(state.queryState) != this.serializeService.serialize(urlQueryState)) {
|
||||
return of(new mapActions.SetState(state.mapState,urlQueryState));
|
||||
}
|
||||
}
|
||||
return EMPTY;
|
||||
})).subscribe((action) => {
|
||||
if(action) {
|
||||
this.zone.run(() => {
|
||||
//console.debug("Url to state");
|
||||
this.store.dispatch(action);
|
||||
});
|
||||
this.paramSub = this.route.paramMap.pipe(withLatestFrom(this.state$), switchMap(([params, state]) => {
|
||||
if (this.initialized && this.noContent) {
|
||||
const urlQueryState = this.getQueryStateFromUrl(params);
|
||||
if (this.serializeService.serialize(state.queryState) != this.serializeService.serialize(urlQueryState)) {
|
||||
return of(new mapActions.SetState(state.mapState, urlQueryState));
|
||||
}
|
||||
});
|
||||
}
|
||||
return EMPTY;
|
||||
})).subscribe((action) => {
|
||||
if (action) {
|
||||
this.zone.run(() => {
|
||||
//console.debug("Url to state");
|
||||
this.store.dispatch(action);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// state to url
|
||||
|
||||
this.stateSub = this.state$.pipe(switchMap((state) => {
|
||||
const newUrl = this.serializeMapState(state.mapState) + "_" + this.serializeService.serialize(state.queryState);
|
||||
if(this.lastUrl!=newUrl) {
|
||||
this.lastUrl=newUrl;
|
||||
if (this.lastUrl != newUrl) {
|
||||
this.lastUrl = newUrl;
|
||||
return of(state);
|
||||
}
|
||||
else {
|
||||
return of(null);
|
||||
}
|
||||
})).subscribe((newUrlState: any) => {
|
||||
if(newUrlState) {
|
||||
//console.debug(`State to url`);
|
||||
this.replaceUrl(newUrlState.mapState,newUrlState.queryState,newUrlState.replaceUrl);
|
||||
}
|
||||
});
|
||||
this.initialized = true;
|
||||
if (newUrlState) {
|
||||
//console.debug(`State to url`);
|
||||
this.replaceUrl(newUrlState.mapState, newUrlState.queryState, newUrlState.replaceUrl);
|
||||
}
|
||||
});
|
||||
this.initialized = true;
|
||||
this.showDataLayerSlide$.subscribe((v) => {
|
||||
this.dataLayerSlideEnabled=v;
|
||||
this.dataLayerSlideEnabled = v;
|
||||
this.map.instance.render();
|
||||
});
|
||||
this.store.select(mapReducers.selectGetViewEnabled).subscribe((v) => {
|
||||
@@ -401,7 +407,7 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
this.store.dispatch(new commonActions.ToggleMenu());
|
||||
}
|
||||
|
||||
handleToggleBaseLayers(event:MouseEvent) {
|
||||
handleToggleBaseLayers(event: MouseEvent) {
|
||||
this.baseLayersCollapsed = !this.baseLayersCollapsed;
|
||||
event.preventDefault();
|
||||
}
|
||||
@@ -418,30 +424,30 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
}
|
||||
|
||||
replaceUrl(mapState: IMapState, queryState: IQueryState, replace = true) {
|
||||
if(this.noContent) {
|
||||
const newMapState = this.serializeMapState(mapState);
|
||||
const newQueryState = this.serializeService.serialize(queryState);
|
||||
const currentMapState = this.serializeMapState(this.getMapStateFromUrl(this.route.snapshot.paramMap));
|
||||
const urlQueryState = this.getQueryStateFromUrl(this.route.snapshot.paramMap);
|
||||
const currentQueryState = urlQueryState==null?"":this.serializeService.serialize(urlQueryState);
|
||||
if(mapState.baseLayerCode!="" && ((newMapState!= currentMapState) || (newQueryState!=currentQueryState))) {
|
||||
const parts =["."];
|
||||
parts.push(mapState.xCenter.toFixed(5));
|
||||
parts.push(mapState.yCenter.toFixed(5));
|
||||
parts.push( mapState.zoom.toFixed(0));
|
||||
parts.push( mapState.rotation.toFixed(2));
|
||||
parts.push(mapState.baseLayerCode);
|
||||
parts.push( this.serializeService.serialize(queryState));
|
||||
|
||||
//console.debug("Replace url",parts);
|
||||
this.router.navigate(parts, { replaceUrl: replace,relativeTo:this.route.parent });
|
||||
}
|
||||
}
|
||||
if (this.noContent) {
|
||||
const newMapState = this.serializeMapState(mapState);
|
||||
const newQueryState = this.serializeService.serialize(queryState);
|
||||
const currentMapState = this.serializeMapState(this.getMapStateFromUrl(this.route.snapshot.paramMap));
|
||||
const urlQueryState = this.getQueryStateFromUrl(this.route.snapshot.paramMap);
|
||||
const currentQueryState = urlQueryState == null ? "" : this.serializeService.serialize(urlQueryState);
|
||||
if (mapState.baseLayerCode != "" && ((newMapState != currentMapState) || (newQueryState != currentQueryState))) {
|
||||
const parts = ["."];
|
||||
parts.push(mapState.xCenter.toFixed(5));
|
||||
parts.push(mapState.yCenter.toFixed(5));
|
||||
parts.push(mapState.zoom.toFixed(0));
|
||||
parts.push(mapState.rotation.toFixed(2));
|
||||
parts.push(mapState.baseLayerCode);
|
||||
parts.push(this.serializeService.serialize(queryState));
|
||||
|
||||
//console.debug("Replace url",parts);
|
||||
this.router.navigate(parts, { replaceUrl: replace, relativeTo: this.route.parent });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleOnMoveEnd(event) {
|
||||
if(this.initialized && this.viewEnabled) {
|
||||
this.zone.run(() =>{
|
||||
handleOnMoveEnd(event) {
|
||||
if (this.initialized && this.viewEnabled) {
|
||||
this.zone.run(() => {
|
||||
//console.debug("Move end");
|
||||
const map = event.map;
|
||||
const view = map.getView();
|
||||
@@ -461,21 +467,23 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleOnMouseDown(event: MouseEvent) {
|
||||
event.stopPropagation();
|
||||
this.zone.run(() =>{
|
||||
this.zone.run(() => {
|
||||
this.store.dispatch(new commonActions.CloseAll());
|
||||
});
|
||||
}
|
||||
|
||||
handleShowLayerValues(event: MouseEvent) {
|
||||
event.stopPropagation();
|
||||
this.zone.run(() =>{
|
||||
this.store.dispatch(new mapActions.ToggleLayerValuesEnabled());
|
||||
});
|
||||
if (!this.hideShowLayerValues) {
|
||||
event.stopPropagation();
|
||||
this.zone.run(() => {
|
||||
this.store.dispatch(new mapActions.ToggleLayerValuesEnabled());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleOnDownload(event) {
|
||||
@@ -491,15 +499,15 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
}
|
||||
|
||||
handleOnToggleVisibility(itemLayer: IItemLayer) {
|
||||
this.store.dispatch(new mapActions.SetVisibility(itemLayer,!itemLayer.visible));
|
||||
this.store.dispatch(new mapActions.SetVisibility(itemLayer, !itemLayer.visible));
|
||||
}
|
||||
|
||||
handleOnSetOpacity(event:{ layer: IItemLayer,opacity:number }) {
|
||||
handleOnSetOpacity(event: { layer: IItemLayer, opacity: number }) {
|
||||
this.store.dispatch(new mapActions.SetOpacity(event.layer, event.opacity));
|
||||
}
|
||||
|
||||
handleZoomToExtent(itemLayer: IItemLayer) {
|
||||
const extent = createEmpty();
|
||||
const extent = createEmpty();
|
||||
extend(extent, itemLayer.layer.getExtent());
|
||||
if (extent) {
|
||||
this.store.dispatch(new mapActions.SetExtent(extent));
|
||||
@@ -514,21 +522,21 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
this.store.dispatch(new mapActions.SelectOverlayLayer(itemLayer));
|
||||
}
|
||||
|
||||
handlePeriodChange(period:IPeriodState) {
|
||||
handlePeriodChange(period: IPeriodState) {
|
||||
this.store.dispatch(new mapActions.SetPeriod(period));
|
||||
}
|
||||
|
||||
handleCitySearch(location:string) {
|
||||
handleCitySearch(location: string) {
|
||||
this.geolocaterService.geocode(location).subscribe(locations => {
|
||||
if( locations.length > 0) {
|
||||
const point = new Point([locations[0].coordinates.lon,locations[0].coordinates.lat]);
|
||||
if (locations.length > 0) {
|
||||
const point = new Point([locations[0].coordinates.lon, locations[0].coordinates.lat]);
|
||||
point.transform('EPSG:4326', 'EPSG:3857');
|
||||
const circle = new Circle(point.getCoordinates(),5000);//
|
||||
const circle = new Circle(point.getCoordinates(), 5000);//
|
||||
const extent = createEmpty();
|
||||
extend(extent, circle.getExtent());
|
||||
this.store.dispatch(new mapActions.SetExtent(extent))
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
||||
@@ -9,9 +9,10 @@ export interface IMetaData {
|
||||
attributes: any
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-meta-data-modal',
|
||||
templateUrl: 'meta-data-modal.component.html'
|
||||
@Component({
|
||||
selector: 'fm-map-meta-data-modal',
|
||||
templateUrl: 'meta-data-modal.component.html',
|
||||
standalone: false
|
||||
})
|
||||
export class MetaDataModalComponent {
|
||||
|
||||
|
||||
@@ -15,10 +15,11 @@ const after = (one: NgbDateStruct, two: NgbDateStruct) =>
|
||||
!one || !two ? false : one.year === two.year ? one.month === two.month ? one.day === two.day
|
||||
? false : one.day > two.day : one.month > two.month : one.year > two.year;
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-select-period-modal',
|
||||
templateUrl: 'select-period-modal.component.html',
|
||||
styleUrls: ['select-period-modal.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-select-period-modal',
|
||||
templateUrl: 'select-period-modal.component.html',
|
||||
styleUrls: ['select-period-modal.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class SelectPeriodModalComponent {
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@ import { WidgetHostDirective } from '../widget-host/widget-host.directive';
|
||||
import { IItemLayer } from '../../models/item.layer';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item-container',
|
||||
templateUrl: './selected-item-container.component.html',
|
||||
styleUrls: ['./selected-item-container.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item-container',
|
||||
templateUrl: './selected-item-container.component.html',
|
||||
styleUrls: ['./selected-item-container.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class SelectedItemContainerComponent {
|
||||
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
<div class="spacer"></div>
|
||||
<div *ngIf="item;let item">
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<div class="card menu-card">
|
||||
<h1>Cropfield</h1>
|
||||
<h4>{{item.name}}</h4>
|
||||
<div class="card-text"><span>{{areaInHa(item)| number:'1.2-2'}} ha</span> <span>{{item.data.cropTypeName}}</span></div>
|
||||
<div class="card-text"><span>{{item.data.startDate|date}}</span> - <span>{{item.data.endDate|date}}</span> </div>
|
||||
<ul class="p-0 mt-2">
|
||||
<li *ngIf="item.isEditable"><a href="#" (click)="handleOnEdit(item)"><i class="fal fa-pencil" aria-hidden="true" i18n-title title="Edit"></i> <span i18n>Edit</span></a></li>
|
||||
</ul>
|
||||
@if (item; as item) {
|
||||
<div>
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<div class="card menu-card">
|
||||
<h1>Cropfield</h1>
|
||||
<h4>{{item.name}}</h4>
|
||||
<div class="card-text"><span>{{areaInHa(item)| number:'1.2-2'}} ha</span> <span>{{item.data.cropTypeName}}</span></div>
|
||||
<div class="card-text"><span>{{item.data.startDate|date}}</span> - <span>{{item.data.endDate|date}}</span> </div>
|
||||
<ul class="p-0 mt-2">
|
||||
@if (item.isEditable) {
|
||||
<li><a href="#" (click)="handleOnEdit(item)"><i class="fal fa-pencil" aria-hidden="true" i18n-title title="Edit"></i> <span i18n>Edit</span></a></li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<fm-map-item-list [items]="(items|async)"></fm-map-item-list>
|
||||
<fm-map-item-widget-list [item]="item"></fm-map-item-widget-list>
|
||||
</div>
|
||||
<fm-map-item-list [items]="(items|async)"></fm-map-item-list>
|
||||
<fm-map-item-widget-list [item]="item"></fm-map-item-widget-list>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -15,17 +15,18 @@ import { withLatestFrom,switchMap,combineLatest } from 'rxjs/operators';
|
||||
|
||||
@ForItemType("vnd.farmmaps.itemtype.cropfield")
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item-cropfield',
|
||||
templateUrl: './selected-item-cropfield.component.html',
|
||||
styleUrls: ['./selected-item-cropfield.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item-cropfield',
|
||||
templateUrl: './selected-item-cropfield.component.html',
|
||||
styleUrls: ['./selected-item-cropfield.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class SelectedItemCropfieldComponent extends AbstractSelectedItemComponent implements OnInit{
|
||||
|
||||
public items: Observable<IListItem[]>;
|
||||
|
||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, location: Location, router: Router, private itemService$: ItemService,private folderService$: FolderService) {
|
||||
super(store, itemTypeService,location,router);
|
||||
super(store, itemTypeService, itemService$, location,router);
|
||||
}
|
||||
|
||||
areaInHa(item:IItem):number {
|
||||
|
||||
@@ -1,34 +1,51 @@
|
||||
<div class="spacer"></div>
|
||||
<div *ngIf="item;let item">
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<div class="card menu-card">
|
||||
<h2 *ngIf="parentOfItemType('vnd.farmmaps.itemtype.cropfield')">{{parentItem.name}}</h2>
|
||||
<h1>{{item.name}}</h1>
|
||||
</div>
|
||||
<div class="legend-container" *ngIf="item?.data.layers;let layers">
|
||||
<div class="card menu-card">
|
||||
<div *ngIf="layers.length>1">
|
||||
<select (change)="onLayerChanged($event.target.value)">
|
||||
<option *ngFor="let l of layers;" [value]="l.index" [selected]="itemLayer.layerIndex == l.index">{{l.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<fm-map-layer-legend [showTitle]="layers.length == 1"
|
||||
[layer]="layer(layers,itemLayer.layerIndex)" [histogramenabled]="true"></fm-map-layer-legend>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card menu-card">
|
||||
<ul class="p-0 mt-2">
|
||||
<li *ngIf="item.isEditable"><a href="#" class="ms-1 me-1" (click)="handleOnEdit(item)"><i class="fal fa-pencil" aria-hidden="true" i18n-title title="Edit"></i> <span i18n>Edit</span></a></li>
|
||||
<ng-container *ngIf="itemTypeService.isLayer(item)">
|
||||
<li *ngIf="!getItemLayer(item,itemLayer.layerIndex)"><a href="#" (click)="handleAddAsLayer(item,itemLayer.layerIndex)"><i class="fas fa-layer-plus" aria-hidden="true" i18n-title title="Add as layer"></i> <span i18n>Add as overlay</span></a></li>
|
||||
<li *ngIf="getItemLayer(item,itemLayer.layerIndex)"><a href="#" (click)="handleRemoveLayer(item,itemLayer.layerIndex)"><i class="fas fa-layer-minus" aria-hidden="true" i18n-title title="Remove overlay"></i> <span i18n>Remove overlay</span></a></li>
|
||||
</ng-container>
|
||||
<li><fm-item-link class="text-primary p-0" [itemCode]="item.code" pathSuffix="data" [showText]="true"></fm-item-link></li>
|
||||
</ul>
|
||||
</div>
|
||||
<fm-map-zoom-to-show-alert [layer]="itemLayer?.layer"></fm-map-zoom-to-show-alert>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
@if (item; as item) {
|
||||
<div>
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<div class="card menu-card">
|
||||
@if (parentOfItemType('vnd.farmmaps.itemtype.cropfield')) {
|
||||
<h2>{{parentItem.name}}</h2>
|
||||
}
|
||||
<h1>{{item.name}}</h1>
|
||||
</div>
|
||||
@if (item?.data.layers; as layers) {
|
||||
<div class="legend-container">
|
||||
<div class="card menu-card">
|
||||
@if (layers.length>1) {
|
||||
<div>
|
||||
<select (change)="onLayerChanged($event.target.value)">
|
||||
@for (l of layers; track l.index) {
|
||||
<option [value]="l.index" [selected]="itemLayer.layerIndex == l.index">{{l.name}}</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
}
|
||||
<fm-map-layer-legend [showTitle]="layers.length == 1"
|
||||
[layer]="layer(layers,itemLayer.layerIndex)" [histogramenabled]="true"></fm-map-layer-legend>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card menu-card">
|
||||
<ul class="p-0 mt-2">
|
||||
@if (item.isEditable) {
|
||||
<li><a href="#" class="ms-1 me-1" (click)="handleOnEdit(item)"><i class="fal fa-pencil" aria-hidden="true" i18n-title title="Edit"></i> <span i18n>Edit</span></a></li>
|
||||
}
|
||||
@if (itemTypeService.isLayer(item)) {
|
||||
@if (!getItemLayer(item,itemLayer.layerIndex)) {
|
||||
<li><a href="#" (click)="handleAddAsLayer(item,itemLayer.layerIndex)"><i class="fas fa-layer-plus" aria-hidden="true" i18n-title title="Add as layer"></i> <span i18n>Add as overlay</span></a></li>
|
||||
}
|
||||
@if (getItemLayer(item,itemLayer.layerIndex)) {
|
||||
<li><a href="#" (click)="handleRemoveLayer(item,itemLayer.layerIndex)"><i class="fas fa-layer-minus" aria-hidden="true" i18n-title title="Remove overlay"></i> <span i18n>Remove overlay</span></a></li>
|
||||
}
|
||||
}
|
||||
<li><fm-item-link class="text-primary p-0" [itemCode]="item.code" pathSuffix="data" [showText]="true"></fm-item-link></li>
|
||||
<li><a href="#" (click)="download($event,item,layers,itemLayer.layerIndex)"><i class="fal fa-download" aria-hidden="true" i18n-title title="Download"></i> <span i18n>Download</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<fm-map-zoom-to-show-alert [layer]="itemLayer?.layer"></fm-map-zoom-to-show-alert>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,25 +1,32 @@
|
||||
import { Component, Injectable } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { Store } from '@ngrx/store';
|
||||
import * as mapReducers from '../../reducers/map.reducer';
|
||||
import { commonReducers, ItemTypeService, ItemService, FolderService } from '@farmmaps/common';
|
||||
import { Component, Injectable, OnDestroy } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { commonReducers, FolderService, IItem, IItemLinkType, ItemService, ItemTypeService, IUrlType } from '@farmmaps/common';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Subscription } from 'rxjs';
|
||||
import * as mapActions from '../../actions/map.actions';
|
||||
import * as mapReducers from '../../reducers/map.reducer';
|
||||
import { ForItemType } from '../for-item/for-itemtype.decorator';
|
||||
import { AbstractSelectedItemComponent } from '../selected-item/selected-item.component';
|
||||
import * as mapActions from '../../actions/map.actions';
|
||||
|
||||
|
||||
@ForItemType("vnd.farmmaps.itemtype.geotiff.processed")
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item-geotiff',
|
||||
templateUrl: './selected-item-geotiff.component.html',
|
||||
styleUrls: ['./selected-item-geotiff.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item-geotiff',
|
||||
templateUrl: './selected-item-geotiff.component.html',
|
||||
styleUrls: ['./selected-item-geotiff.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class SelectedItemGeotiffComponent extends AbstractSelectedItemComponent {
|
||||
export class SelectedItemGeotiffComponent extends AbstractSelectedItemComponent implements OnDestroy {
|
||||
sub: Subscription;
|
||||
|
||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, location: Location, router: Router, private itemService$: ItemService,private folderService$: FolderService) {
|
||||
super(store, itemTypeService,location,router);
|
||||
constructor(store: Store<mapReducers.State | commonReducers.State>, public itemService: ItemService, itemTypeService: ItemTypeService, location: Location, router: Router, private itemService$: ItemService,private folderService$: FolderService) {
|
||||
super(store, itemTypeService,itemService,location,router);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.sub) this.sub.unsubscribe();
|
||||
}
|
||||
|
||||
onLayerChanged(layerIndex: number) {
|
||||
@@ -29,4 +36,13 @@ export class SelectedItemGeotiffComponent extends AbstractSelectedItemComponent
|
||||
layer(layers:any,layerIndex:number) {
|
||||
return layers.find(l => l.index == layerIndex);
|
||||
}
|
||||
|
||||
download(event:MouseEvent,item:IItem,layers:any,layerIndex:number) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
const itemLink : IItemLinkType = {itemcode:item.code,query:`layer=${this.layer(layers,layerIndex).name}`,pathsuffix:"download", validminutes:10}
|
||||
this.sub = this.itemService.getItemLink(itemLink).subscribe((itemLinkUrl:IUrlType) => {
|
||||
window.location.href = itemLinkUrl.url;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,49 @@
|
||||
<div class="spacer"></div>
|
||||
<div *ngIf="item;let item">
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<div class="card menu-card">
|
||||
<h2 *ngIf="parentOfItemType('vnd.farmmaps.itemtype.cropfield')">{{parentItem.name}}</h2>
|
||||
<h1>{{item.name}}</h1>
|
||||
</div>
|
||||
<div class="legend-container" *ngIf="item?.data.layers;let layers">
|
||||
@if (item; as item) {
|
||||
<div>
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<div class="card menu-card">
|
||||
<div *ngIf="layers.length>1">
|
||||
<select (change)="onLayerChanged($event.target.value)">
|
||||
<option *ngFor="let l of layers;" [value]="l.index" [selected]="itemLayer.layerIndex == l.index">{{l.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<fm-map-layer-legend [showTitle]="layers.length==1" [layer]="layer(layers,itemLayer.layerIndex)" [histogramenabled]="true"></fm-map-layer-legend>
|
||||
@if (parentOfItemType('vnd.farmmaps.itemtype.cropfield')) {
|
||||
<h2>{{parentItem.name}}</h2>
|
||||
}
|
||||
<h1>{{item.name}}</h1>
|
||||
</div>
|
||||
@if (item?.data.layers; as layers) {
|
||||
<div class="legend-container">
|
||||
<div class="card menu-card">
|
||||
@if (layers.length>1) {
|
||||
<div>
|
||||
<select (change)="onLayerChanged($event.target.value)">
|
||||
@for (l of layers; track l.index) {
|
||||
<option [value]="l.index" [selected]="itemLayer.layerIndex == l.index">{{l.name}}</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
}
|
||||
<fm-map-layer-legend [showTitle]="layers.length==1" [layer]="layer(layers,itemLayer.layerIndex)" [histogramenabled]="true"></fm-map-layer-legend>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card menu-card">
|
||||
<ul class="p-0 mt-2">
|
||||
@if (item.isEditable) {
|
||||
<li><a href="#" class="mt-1 me-1" (click)="handleOnEdit(item)" ><i class="fal fa-pencil" aria-hidden="true" i18n-title title="Edit"></i> <span i18n>Edit</span></a></li>
|
||||
}
|
||||
@if (itemTypeService.isLayer(item)) {
|
||||
@if (!getItemLayer(item,itemLayer.layerIndex)) {
|
||||
<li><a href="#" (click)="handleAddAsLayer(item,itemLayer.layerIndex)" ><i class="fas fa-layer-olus" aria-hidden="true" i18n-title title="Add as layer"></i> <span i18n>Add as overlay</span></a></li>
|
||||
}
|
||||
@if (getItemLayer(item,itemLayer.layerIndex)) {
|
||||
<li><a href="#" (click)="handleRemoveLayer(item,itemLayer.layerIndex)" ><i class="fas fa-layer-minus" aria-hidden="true" i18n-title title="Remove overlay"></i> <span i18n>Remove overlay</span></a></li>
|
||||
}
|
||||
}
|
||||
<li><a href="#" (click)="download($event,item,layers,itemLayer.layerIndex)"><i class="fal fa-download" aria-hidden="true" i18n-title title="Download"></i> <span i18n>Download</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
<fm-map-zoom-to-show-alert [layer]="itemLayer?.layer"></fm-map-zoom-to-show-alert>
|
||||
</div>
|
||||
<div class="card menu-card">
|
||||
<ul class="p-0 mt-2">
|
||||
<li *ngIf="item.isEditable"><a href="#" class="mt-1 me-1" (click)="handleOnEdit(item)" ><i class="fal fa-pencil" aria-hidden="true" i18n-title title="Edit"></i> <span i18n>Edit</span></a></li>
|
||||
<ng-container *ngIf="itemTypeService.isLayer(item)">
|
||||
<li *ngIf="!getItemLayer(item,itemLayer.layerIndex)"><a href="#" (click)="handleAddAsLayer(item,itemLayer.layerIndex)" ><i class="fas fa-layer-olus" aria-hidden="true" i18n-title title="Add as layer"></i> <span i18n>Add as overlay</span></a></li>
|
||||
<li *ngIf="getItemLayer(item,itemLayer.layerIndex)"><a href="#" (click)="handleRemoveLayer(item,itemLayer.layerIndex)" ><i class="fas fa-layer-minus" aria-hidden="true" i18n-title title="Remove overlay"></i> <span i18n>Remove overlay</span></a></li>
|
||||
</ng-container>
|
||||
</ul>
|
||||
</div>
|
||||
<fm-map-zoom-to-show-alert [layer]="itemLayer?.layer"></fm-map-zoom-to-show-alert>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,30 +1,35 @@
|
||||
import { Component, Input, Injectable, OnInit } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { Feature } from 'ol';
|
||||
import { Component, Injectable, OnDestroy } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { commonReducers, FolderService, IItem, IItemLinkType, ItemService, ItemTypeService, IUrlType } from '@farmmaps/common';
|
||||
import { Store } from '@ngrx/store';
|
||||
import * as mapReducers from '../../reducers/map.reducer';
|
||||
import { commonReducers, ItemTypeService, IItem, Item, ItemService, FolderService, IListItem} from '@farmmaps/common';
|
||||
import * as mapActions from '../../actions/map.actions';
|
||||
import { Router, ActivatedRoute, ParamMap, Event } from '@angular/router';
|
||||
import * as mapReducers from '../../reducers/map.reducer';
|
||||
import { ForItemType } from '../for-item/for-itemtype.decorator';
|
||||
import { AbstractSelectedItemComponent } from '../selected-item/selected-item.component';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
|
||||
@ForItemType("vnd.farmmaps.itemtype.shape.processed")
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item-shape',
|
||||
templateUrl: './selected-item-shape.component.html',
|
||||
styleUrls: ['./selected-item-shape.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item-shape',
|
||||
templateUrl: './selected-item-shape.component.html',
|
||||
styleUrls: ['./selected-item-shape.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class SelectedItemShapeComponent extends AbstractSelectedItemComponent {
|
||||
|
||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, location: Location, router: Router, private itemService$: ItemService,private folderService$: FolderService) {
|
||||
super(store, itemTypeService,location,router);
|
||||
}
|
||||
export class SelectedItemShapeComponent extends AbstractSelectedItemComponent implements OnDestroy {
|
||||
public selectedLayer = 0;
|
||||
|
||||
sub: Subscription;
|
||||
|
||||
constructor(store: Store<mapReducers.State | commonReducers.State>, public itemService: ItemService, itemTypeService: ItemTypeService, location: Location, router: Router, private itemService$: ItemService,private folderService$: FolderService) {
|
||||
super(store, itemTypeService,itemService,location,router);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.sub) this.sub.unsubscribe();
|
||||
}
|
||||
|
||||
onLayerChanged(layerIndex: number) {
|
||||
this.store.dispatch(new mapActions.SetLayerIndex(layerIndex));
|
||||
}
|
||||
@@ -32,4 +37,13 @@ export class SelectedItemShapeComponent extends AbstractSelectedItemComponent {
|
||||
layer(layers:any,layerIndex:number) {
|
||||
return layers.find(l => l.index == layerIndex);
|
||||
}
|
||||
|
||||
download(event:MouseEvent,item:IItem,layers:any,layerIndex:number) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
const itemLink : IItemLinkType = {itemcode:item.code,query:`layer=${this.layer(layers,layerIndex).name}`,pathsuffix:"download", validminutes:10}
|
||||
this.sub = this.itemService.getItemLink(itemLink).subscribe((itemLinkUrl:IUrlType) => {
|
||||
window.location.href = itemLinkUrl.url;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,70 @@
|
||||
<div class="spacer"></div>
|
||||
<div *ngIf="selectedItem();let item">
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<div class="card menu-card">
|
||||
<h2 *ngIf="parentOfItemType('vnd.farmmaps.itemtype.cropfield')">{{parentItem.name}}</h2>
|
||||
<h1>{{item.name}}</h1>
|
||||
</div>
|
||||
<div class="legend-container" *ngIf="item?.data.layers;let layers">
|
||||
<div class="card menu-card">
|
||||
<h5><span i18n>Date</span>: {{temporalService.selectedDate(itemLayer)}}</h5>
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<button *ngIf="temporalService.hasPrevious(itemLayer)" type="button" class="btn btn-link p-0" (click)="handlePreviousTemporal($event)">
|
||||
<i class="fal fa-arrow-circle-left" aria-hidden="true" i18n-title title="Previous"></i> {{ temporalService.previousDate(itemLayer) }}
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button *ngIf="temporalService.hasNext(itemLayer)" type="button" class="btn btn-link p-0" (click)="handleNextTemporal($event)">
|
||||
{{ temporalService.nextDate(itemLayer)}} <i class="fal fa-arrow-circle-right" aria-hidden="true" i18n-title title="Next"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<fm-map-zoom-to-show-alert [layer]="currentItemLayer()?.layer"></fm-map-zoom-to-show-alert>
|
||||
</div>
|
||||
<div class="card menu-card pt-2">
|
||||
<div *ngIf="layers.length>1">
|
||||
<select (change)="onLayerChanged($event.target.value)">
|
||||
<option *ngFor="let l of layers;" [value]="l.index" [selected]="itemLayer.layerIndex == l.index">{{l.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<fm-map-layer-legend [showTitle]="layers.length == 1"
|
||||
[layer]="layer(layers,itemLayer.layerIndex)" [histogramenabled]="true"></fm-map-layer-legend>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card menu-card">
|
||||
<ul class="p-0 mt-2">
|
||||
<li *ngIf="item.isEditable"><a href="#" class="mt-1 me-1" (click)="handleOnEdit(item)"><i class="fal fa-pencil" aria-hidden="true" i18n-title title="Edit"></i> <span i18n>Edit</span></a></li>
|
||||
<ng-container *ngIf="itemTypeService.isLayer(item)">
|
||||
<li *ngIf="!getItemLayer(item,itemLayer.layerIndex)"><a href="#" (click)="handleAddAsLayer(item,itemLayer.layerIndex)"><i class="fas fa-layer-plus" aria-hidden="true" i18n-title title="Add as layer"></i> <span i18n>Add as overlay</span></a></li>
|
||||
<li *ngIf="getItemLayer(item,itemLayer.layerIndex)"><a href="#" (click)="handleRemoveLayer(item,itemLayer.layerIndex)"><i class="fas fa-layer-minus" aria-hidden="true" i18n-title title="Remove overlay"></i> <span i18n>Remove overlay</span></a></li>
|
||||
</ng-container>
|
||||
<li><a href="#" (click)="handleGoToChart(item)"><i class="fal fa-line-chart" aria-hidden="true" i18m-title title="Show chart"></i> <span i18n>Show chart</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
@if (selectedItem(); as item) {
|
||||
<div>
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<div class="card menu-card">
|
||||
@if (parentOfItemType('vnd.farmmaps.itemtype.cropfield')) {
|
||||
<h2>{{parentItem.name}}</h2>
|
||||
}
|
||||
<h1>{{item.name}}</h1>
|
||||
</div>
|
||||
@if (item?.data.layers; as layers) {
|
||||
<div class="legend-container">
|
||||
<div class="card menu-card">
|
||||
<h5><span i18n>Date</span>: {{temporalService.selectedDate(itemLayer)}}</h5>
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
@if (temporalService.hasPrevious(itemLayer)) {
|
||||
<button type="button" class="btn btn-link p-0" (click)="handlePreviousTemporal($event)">
|
||||
<i class="fal fa-arrow-circle-left" aria-hidden="true" i18n-title title="Previous"></i> {{ temporalService.previousDate(itemLayer) }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
@if (temporalService.hasNext(itemLayer)) {
|
||||
<button type="button" class="btn btn-link p-0" (click)="handleNextTemporal($event)">
|
||||
{{ temporalService.nextDate(itemLayer)}} <i class="fal fa-arrow-circle-right" aria-hidden="true" i18n-title title="Next"></i>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<fm-map-zoom-to-show-alert [layer]="currentItemLayer()?.layer"></fm-map-zoom-to-show-alert>
|
||||
</div>
|
||||
<div class="card menu-card pt-2">
|
||||
@if (layers.length>1) {
|
||||
<div>
|
||||
<select (change)="onLayerChanged($event.target.value)">
|
||||
@for (l of layers; track l.index) {
|
||||
<option [value]="l.index" [selected]="itemLayer.layerIndex == l.index">{{l.name}}</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
}
|
||||
<fm-map-layer-legend [showTitle]="layers.length == 1"
|
||||
[layer]="layer(layers,itemLayer.layerIndex)" [histogramenabled]="true"></fm-map-layer-legend>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card menu-card">
|
||||
<ul class="p-0 mt-2">
|
||||
@if (item.isEditable) {
|
||||
<li><a href="#" class="mt-1 me-1" (click)="handleOnEdit(item)"><i class="fal fa-pencil" aria-hidden="true" i18n-title title="Edit"></i> <span i18n>Edit</span></a></li>
|
||||
}
|
||||
@if (itemTypeService.isLayer(item)) {
|
||||
@if (!getItemLayer(item,itemLayer.layerIndex)) {
|
||||
<li><a href="#" (click)="handleAddAsLayer(item,itemLayer.layerIndex)"><i class="fas fa-layer-plus" aria-hidden="true" i18n-title title="Add as layer"></i> <span i18n>Add as overlay</span></a></li>
|
||||
}
|
||||
@if (getItemLayer(item,itemLayer.layerIndex)) {
|
||||
<li><a href="#" (click)="handleRemoveLayer(item,itemLayer.layerIndex)"><i class="fas fa-layer-minus" aria-hidden="true" i18n-title title="Remove overlay"></i> <span i18n>Remove overlay</span></a></li>
|
||||
}
|
||||
}
|
||||
<li><a href="#" (click)="handleGoToChart(item)"><i class="fal fa-line-chart" aria-hidden="true" i18m-title title="Show chart"></i> <span i18n>Show chart</span></a></li>
|
||||
<li><a href="#" (click)="download($event,item,layers,itemLayer.layerIndex)"><i class="fal fa-download" aria-hidden="true" i18n-title title="Download"></i> <span i18n>Download</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
import { Component, Injectable } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { Store } from '@ngrx/store';
|
||||
import * as mapReducers from '../../reducers/map.reducer';
|
||||
import { commonReducers, ItemTypeService, IItem } from '@farmmaps/common';
|
||||
import { Component, Injectable, OnDestroy } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { commonReducers, IItem, IItemLinkType, ItemService, ItemTypeService, IUrlType } from '@farmmaps/common';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Subscription } from 'rxjs';
|
||||
import * as mapActions from '../../actions/map.actions';
|
||||
import { IItemLayer, ITemporalItemLayer } from '../../models/item.layer';
|
||||
import * as mapReducers from '../../reducers/map.reducer';
|
||||
import { TemporalService } from '../../services/temporal.service';
|
||||
import { ForItemType } from '../for-item/for-itemtype.decorator';
|
||||
import { AbstractSelectedItemComponent } from '../selected-item/selected-item.component';
|
||||
import { ITemporalItemLayer} from '../../models/item.layer';
|
||||
import * as mapActions from '../../actions/map.actions';
|
||||
import { IItemLayer } from '../../models/item.layer';
|
||||
import {TemporalService} from '../../services/temporal.service';
|
||||
|
||||
|
||||
@ForItemType("vnd.farmmaps.itemtype.temporal")
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item-temporal',
|
||||
templateUrl: './selected-item-temporal.component.html',
|
||||
styleUrls: ['./selected-item-temporal.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item-temporal',
|
||||
templateUrl: './selected-item-temporal.component.html',
|
||||
styleUrls: ['./selected-item-temporal.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class SelectedItemTemporalComponent extends AbstractSelectedItemComponent {
|
||||
export class SelectedItemTemporalComponent extends AbstractSelectedItemComponent implements OnDestroy {
|
||||
sub: Subscription;
|
||||
|
||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, location: Location, router: Router,public temporalService:TemporalService) {
|
||||
super(store, itemTypeService,location,router);
|
||||
constructor(store: Store<mapReducers.State | commonReducers.State>, public itemService: ItemService, itemTypeService: ItemTypeService, location: Location, router: Router,public temporalService:TemporalService) {
|
||||
super(store, itemTypeService,itemService,location,router);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.sub) this.sub.unsubscribe();
|
||||
}
|
||||
|
||||
onLayerChanged(layerIndex: number) {
|
||||
@@ -33,8 +38,6 @@ export class SelectedItemTemporalComponent extends AbstractSelectedItemComponent
|
||||
return (this.itemLayer as ITemporalItemLayer)?.selectedItemLayer
|
||||
}
|
||||
|
||||
|
||||
|
||||
handleNextTemporal(event:MouseEvent) {
|
||||
this.store.dispatch(new mapActions.NextTemporal());
|
||||
event.preventDefault();
|
||||
@@ -61,4 +64,13 @@ export class SelectedItemTemporalComponent extends AbstractSelectedItemComponent
|
||||
this.router.navigate(['/viewer', 'temporal', 'item', item.parentCode, new Date(Date.parse(item.dataDate)).getUTCFullYear()]);
|
||||
return false;
|
||||
}
|
||||
|
||||
download(event:MouseEvent,item:IItem,layers:any,layerIndex:number) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
const itemLink : IItemLinkType = {itemcode:item.code,query:`layer=${this.layer(layers,layerIndex).name}`,pathsuffix:"download", validminutes:10}
|
||||
this.sub = this.itemService.getItemLink(itemLink).subscribe((itemLinkUrl:IUrlType) => {
|
||||
window.location.href = itemLinkUrl.url;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,31 @@
|
||||
<div *ngIf="item;let item">
|
||||
<div class="card border-0">
|
||||
<fm-thumbnail [item]="item" [edit]="item.isEditable"></fm-thumbnail>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<h1 class="card-title">{{item.name}}</h1>
|
||||
<div class="card menu-card">
|
||||
<ul class="p-0 mt-2">
|
||||
<li *ngIf="itemTypeService.hasViewer(item)"><a href="#" (click)="handleOnView(item)" class="btn btn-outline-secondary"><i class="fal fa-eye" aria-hidden="true" title="View"></i> <span i18n>View</span></a></li>
|
||||
<li *ngIf="item.isEditable"><a href="#" (click)="handleOnEdit(item)"><i class="fal fa-pencil" aria-hidden="true" title="Edit"></i> <span i18n>Edit</span></a></li>
|
||||
<ng-container *ngIf="itemTypeService.isLayer(item)">
|
||||
<li *ngIf="!getItemLayer(item)"><a href="#" (click)="handleAddAsLayer(item)"><i class="fas fa-layer-plus" aria-hidden="true" i18n-title title="Add as layer"></i> <span i18n>Add as overlay</span></a></li>
|
||||
<li *ngIf="getItemLayer(item)"><a href="#" (click)="handleRemoveLayer(item)"><i class="fas fa-layer-minus" aria-hidden="true" i18n-title title="Remove overlay"></i> <span i18n>Remove overlay</span></a></li>
|
||||
</ng-container>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (item; as item) {
|
||||
<div>
|
||||
<div class="card border-0">
|
||||
<fm-thumbnail [item]="item" [edit]="item.isEditable"></fm-thumbnail>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<fm-back-button></fm-back-button>
|
||||
<h1 class="card-title">{{item.name}}</h1>
|
||||
<div class="card menu-card">
|
||||
<ul class="p-0 mt-2">
|
||||
@if (itemTypeService.hasViewer(item)) {
|
||||
<li><a href="#" (click)="handleOnView(item)" class="btn btn-outline-secondary"><i class="fal fa-eye" aria-hidden="true" title="View"></i> <span i18n>View</span></a></li>
|
||||
}
|
||||
@if (item.isEditable) {
|
||||
<li><a href="#" (click)="handleOnEdit(item)"><i class="fal fa-pencil" aria-hidden="true" title="Edit"></i> <span i18n>Edit</span></a></li>
|
||||
}
|
||||
@if (itemTypeService.isLayer(item)) {
|
||||
@if (!getItemLayer(item)) {
|
||||
<li><a href="#" (click)="handleAddAsLayer(item)"><i class="fas fa-layer-plus" aria-hidden="true" i18n-title title="Add as layer"></i> <span i18n>Add as overlay</span></a></li>
|
||||
}
|
||||
@if (getItemLayer(item)) {
|
||||
<li ><a href="#" (click)="handleRemoveLayer(item)"><i class="fas fa-layer-minus" aria-hidden="true" i18n-title title="Remove overlay"></i> <span i18n>Remove overlay</span></a></li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import {Component, Injectable, Input, Directive} from '@angular/core';
|
||||
import {Location} from '@angular/common';
|
||||
import {Store} from '@ngrx/store';
|
||||
import * as mapReducers from '../../reducers/map.reducer';
|
||||
import {AppConfig, commonReducers, IItem, ItemTypeService} from '@farmmaps/common';
|
||||
import {AppConfig, commonReducers, IItem, ItemService, ItemTypeService} from '@farmmaps/common';
|
||||
import * as mapActions from '../../actions/map.actions';
|
||||
import {Router} from '@angular/router';
|
||||
import { IItemLayer } from '../../models/item.layer';
|
||||
@@ -15,7 +15,7 @@ export abstract class AbstractSelectedItemComponent {
|
||||
@Input() parentItem: IItem;
|
||||
@Input() itemLayer: IItemLayer;
|
||||
@Input() overlayLayers: Array<IItemLayer>;
|
||||
constructor(public store: Store<mapReducers.State | commonReducers.State>, public itemTypeService: ItemTypeService, private location: Location, public router: Router) {
|
||||
constructor(public store: Store<mapReducers.State | commonReducers.State>, public itemTypeService: ItemTypeService, public itemService: ItemService, private location: Location, public router: Router) {
|
||||
}
|
||||
|
||||
handleOnView(item: IItem) {
|
||||
@@ -37,6 +37,11 @@ export abstract class AbstractSelectedItemComponent {
|
||||
return false;
|
||||
}
|
||||
|
||||
handleOnDelete(item: IItem) {
|
||||
this.itemService.deleteItem(item.code);
|
||||
return false;
|
||||
}
|
||||
|
||||
handleAddAsLayer(item: IItem,layerIndex = -1) {
|
||||
this.store.dispatch(new mapActions.AddLayer(item,layerIndex));
|
||||
return false;
|
||||
@@ -69,15 +74,16 @@ export abstract class AbstractSelectedItemComponent {
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item',
|
||||
templateUrl: './selected-item.component.html',
|
||||
styleUrls: ['./selected-item.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map-selected-item',
|
||||
templateUrl: './selected-item.component.html',
|
||||
styleUrls: ['./selected-item.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class SelectedItemComponent extends AbstractSelectedItemComponent {
|
||||
|
||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, location: Location, router: Router, public config:AppConfig) {
|
||||
super(store, itemTypeService,location,router);
|
||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, itemService: ItemService, location: Location, router: Router, public config:AppConfig) {
|
||||
super(store, itemTypeService,itemService,location,router);
|
||||
}
|
||||
|
||||
getThumbnailUrl(item:IItem):string {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Directive, ViewContainerRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[fm-map-widget-host]',
|
||||
selector: '[fm-map-widget-host]',
|
||||
standalone: false
|
||||
})
|
||||
export class WidgetHostDirective {
|
||||
constructor(public viewContainerRef: ViewContainerRef) { }
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
<div [ngSwitch]="stage">
|
||||
<h6 *ngSwitchCase="StageEnum.DevelopmentPreAlpha" style="color:darkred" [ngbTooltip]="info"><b><span i18n>Stage:Pre-alpha</span></b></h6>
|
||||
<h6 *ngSwitchCase="StageEnum.DevelopmentAlpha" style="color:red" [ngbTooltip]="info"><b><span i18n>Stage:Alpha</span></b></h6>
|
||||
<h6 *ngSwitchCase="StageEnum.DevelopmentBeta" style="color:orange" [ngbTooltip]="info" ><b><span i18n>Stage:Beta</span></b></h6>
|
||||
<h6 *ngSwitchCase="StageEnum.ReleaseCandidate" style="color:green" [ngbTooltip]="info" ><b><span i18n>Stage:RC</span></b></h6>
|
||||
</div>
|
||||
<div>
|
||||
@switch (stage) {
|
||||
@case (StageEnum.DevelopmentPreAlpha) {
|
||||
<h6 style="color:darkred" [ngbTooltip]="info"><b><span i18n>Stage:Pre-alpha</span></b></h6>
|
||||
}
|
||||
@case (StageEnum.DevelopmentAlpha) {
|
||||
<h6 style="color:red" [ngbTooltip]="info"><b><span i18n>Stage:Alpha</span></b></h6>
|
||||
}
|
||||
@case (StageEnum.DevelopmentBeta) {
|
||||
<h6 style="color:orange" [ngbTooltip]="info" ><b><span i18n>Stage:Beta</span></b></h6>
|
||||
}
|
||||
@case (StageEnum.ReleaseCandidate) {
|
||||
<h6 style="color:green" [ngbTooltip]="info" ><b><span i18n>Stage:RC</span></b></h6>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-widget-status',
|
||||
templateUrl: './widget-status.component.html',
|
||||
styleUrls: ['./widget-status.component.css']
|
||||
selector: 'fm-map-widget-status',
|
||||
templateUrl: './widget-status.component.html',
|
||||
styleUrls: ['./widget-status.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class WidgetStatusComponent implements OnInit {
|
||||
@Input() stage: Stage;
|
||||
|
||||
@@ -2,9 +2,10 @@ import { Component, Input } from '@angular/core';
|
||||
import { Layer } from 'ol/layer';
|
||||
import { Source } from 'ol/source';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-zoom-to-show-alert',
|
||||
template: '<div *fmMapIfZoomToShow="layer$" class="alert alert-info"><i class="fas fa-search-plus" aria-hidden="true" i18n-title title="Add as layer"></i> <span i18n>Zoom in to show layer</span></div>'
|
||||
@Component({
|
||||
selector: 'fm-map-zoom-to-show-alert',
|
||||
template: '<div *fmMapIfZoomToShow="layer$" class="alert alert-info"><i class="fas fa-search-plus" aria-hidden="true" i18n-title title="Add as layer"></i> <span i18n>Zoom in to show layer</span></div>',
|
||||
standalone: false
|
||||
})
|
||||
export class ZoomToShowAlert {
|
||||
public layer$: Layer<Source>;
|
||||
|
||||
@@ -133,7 +133,7 @@ export class MapEffects {
|
||||
f.id = f.properties["code"];
|
||||
}
|
||||
}
|
||||
return of(new mapActions.StartSearchSuccess(this._geojsonFormat.readFeatures(features), a.queryState));
|
||||
return of(new mapActions.StartSearchSuccess(this._geojsonFormat.readFeatures(features).filter(feature => feature instanceof Feature) as Feature[], a.queryState));
|
||||
}
|
||||
),
|
||||
catchError(error => of(new commonActions.Fail(error))));
|
||||
@@ -166,12 +166,14 @@ export class MapEffects {
|
||||
zoomToExtent2$ = createEffect(() => this.actions$.pipe(
|
||||
ofType(mapActions.SETFEATURES),
|
||||
switchMap((action: mapActions.SetFeatures) => {
|
||||
const extent = createEmpty();
|
||||
if (extent) {
|
||||
for (const f of action.features) {
|
||||
extend(extent, (f as Feature<Geometry>).getGeometry().getExtent());
|
||||
if (action.zoomToExtent) {
|
||||
const extent = createEmpty();
|
||||
if (extent) {
|
||||
for (const f of action.features) {
|
||||
extend(extent, (f as Feature<Geometry>).getGeometry().getExtent());
|
||||
}
|
||||
if (action.features.length > 0) return of(new mapActions.SetExtent(extent));
|
||||
}
|
||||
if (action.features.length > 0) return of(new mapActions.SetExtent(extent));
|
||||
}
|
||||
return EMPTY;
|
||||
})));
|
||||
@@ -218,7 +220,7 @@ export class MapEffects {
|
||||
if (!this.overrideSelectedItemLayer) {
|
||||
return this.itemService$.getFeature(action.item.code, "EPSG:3857").pipe(
|
||||
map((feature: any) => {
|
||||
const f = this._geojsonFormat.readFeature(feature);
|
||||
const f = this._geojsonFormat.readFeature(feature) as Feature;
|
||||
f.setId(action.item.code);
|
||||
return new mapActions.AddFeatureSuccess(f);
|
||||
}),
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ILayervalue } from '../models/layer.value';
|
||||
import * as mapActions from '../actions/map.actions';
|
||||
import {commonActions} from '@farmmaps/common';
|
||||
import { createSelector, createFeatureSelector } from '@ngrx/store';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import {Feature} from 'ol';
|
||||
import {Geometry} from 'ol/geom';
|
||||
@@ -47,6 +48,7 @@ export interface State {
|
||||
query:IQuery,
|
||||
parentCode: string,
|
||||
features: Array<Feature<Geometry>>,
|
||||
featuresBackup: Array<Feature<Geometry>>,
|
||||
panelVisible: boolean,
|
||||
panelCollapsed: boolean,
|
||||
panelExtraWide: boolean,
|
||||
@@ -93,6 +95,7 @@ export const initialState: State = {
|
||||
query: null,
|
||||
parentCode: null,
|
||||
features: [],
|
||||
featuresBackup: [],
|
||||
panelVisible: false,
|
||||
panelCollapsed: false,
|
||||
panelExtraWide: false,
|
||||
@@ -156,13 +159,15 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
const a = action as mapActions.StartSearchSuccess;
|
||||
return tassign(state, {
|
||||
features: a.features,
|
||||
featuresBackup: [],
|
||||
inSearch:false
|
||||
});
|
||||
}
|
||||
case mapActions.SETFEATURES: {
|
||||
const a = action as mapActions.SetFeatures;
|
||||
return tassign(state, {
|
||||
features: a.features
|
||||
features: a.features,
|
||||
featuresBackup: []
|
||||
});
|
||||
}
|
||||
case mapActions.SELECTFEATURE: {
|
||||
@@ -180,6 +185,7 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
selectedItemLayer: null,
|
||||
showDataLayerSlide: false,
|
||||
features:[],
|
||||
featuresBackup: [],
|
||||
inSearch:inSearch
|
||||
});
|
||||
}
|
||||
@@ -296,6 +302,7 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
return tassign(state, {
|
||||
selectedItem: null,
|
||||
features:[],
|
||||
featuresBackup: [],
|
||||
selectedItemLayer:null,
|
||||
searchCollapsed: !panelVisible,
|
||||
panelVisible: panelVisible,
|
||||
@@ -332,7 +339,8 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
extent: a.feature.getGeometry().getExtent(),
|
||||
searchCollapsed: false,
|
||||
clearEnabled:true,
|
||||
features:features
|
||||
features:features,
|
||||
featuresBackup:[]
|
||||
});
|
||||
}
|
||||
case mapActions.UPDATEFEATURESUCCESS: {
|
||||
@@ -346,7 +354,7 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
features.push(state.features[i]);
|
||||
}
|
||||
}
|
||||
return tassign(state, { features: features });
|
||||
return tassign(state, { features: features, featuresBackup: [] });
|
||||
}
|
||||
case mapActions.EXPANDSEARCH: {
|
||||
return tassign(state, { searchCollapsed: false });
|
||||
@@ -391,7 +399,7 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
return tassign(state, {overlayLayers: [], selectedOverlayLayer: null});
|
||||
}
|
||||
case mapActions.CLEARFEATURES: {
|
||||
return tassign(state, {features: [], selectedFeature: null});
|
||||
return tassign(state, {features: [], featuresBackup: [], selectedFeature: null});
|
||||
}
|
||||
case mapActions.SETVISIBILITY: {
|
||||
const a = action as mapActions.SetVisibility;
|
||||
@@ -509,6 +517,7 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
searchCollapsed: true,
|
||||
searchMinified: false,
|
||||
features: [],
|
||||
featuresBackup: [],
|
||||
query:initialState.query,
|
||||
showLayerSwitcher: false,
|
||||
extent: null,
|
||||
@@ -556,7 +565,8 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
selectedItem: null,
|
||||
selectedItemLayer: null,
|
||||
showDataLayerSlide: false,
|
||||
features:[]
|
||||
features:[],
|
||||
featuresBackup:[]
|
||||
});
|
||||
}
|
||||
if(state.features.length>0) {
|
||||
@@ -569,7 +579,7 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
if(index>=0) {
|
||||
const newFeatures = state.features.slice(0);
|
||||
newFeatures.splice(index,1);
|
||||
return tassign(state,{features:newFeatures});
|
||||
return tassign(state,{features:newFeatures, featuresBackup:[]});
|
||||
}
|
||||
}
|
||||
return state;
|
||||
@@ -578,6 +588,17 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
const a= action as mapActions.SetPanelExtraWide;
|
||||
return tassign(state,{panelExtraWide:a.panelExtraWide});
|
||||
}
|
||||
case mapActions.BACKUPFEATURES: {
|
||||
return tassign(state, {
|
||||
featuresBackup: _.cloneDeep(state.features)
|
||||
});
|
||||
}
|
||||
case mapActions.RESTOREFEATURES: {
|
||||
return tassign(state, {
|
||||
features: _.cloneDeep(state.featuresBackup),
|
||||
featuresBackup: []
|
||||
});
|
||||
}
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
@@ -637,6 +658,8 @@ export const selectGetExtent = createSelector(selectMapState, getExtent);
|
||||
export const selectGetViewExtent = createSelector(selectMapState, getViewExtent);
|
||||
export const selectGetOverlayLayers = createSelector(selectMapState, getOverlayLayers);
|
||||
export const selectGetBaseLayers = createSelector(selectMapState, getBaseLayers);
|
||||
export const selectGetBaseMaps = createSelector(selectGetBaseLayers, (layers) => layers.filter(layer => layer.item.data.category === "baseMap"));
|
||||
export const selectGetArealMaps = createSelector(selectGetBaseLayers, (layers) => layers.filter(layer => layer.item.data.category === "aerialPhoto").sort((a, b) => a.item.dataDate <= b.item.dataDate ? 1 : -1));
|
||||
export const selectGetProjection = createSelector(selectMapState, getProjection);
|
||||
export const selectGetSelectedBaseLayer = createSelector(selectMapState, getSelectedBaseLayer);
|
||||
export const selectGetSelectedOverlayLayer = createSelector(selectMapState, getSelectedOverlayLayer);
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'core-js/es7/reflect';
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting(), {
|
||||
teardown: { destroyAfterEach: false }
|
||||
}
|
||||
);
|
||||
@@ -3,7 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/lib",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"moduleResolution": "bundler",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
@@ -12,15 +12,9 @@
|
||||
"importHelpers": true,
|
||||
"esModuleInterop": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
],
|
||||
"paths": {
|
||||
"@angular/*": [
|
||||
|
||||
"node_modules/@angular/*"
|
||||
|
||||
"node_modules/@angular/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -33,7 +27,6 @@
|
||||
"compilationMode": "partial"
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/lib",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"moduleResolution": "bundler",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
@@ -12,15 +12,9 @@
|
||||
"importHelpers": true,
|
||||
"esModuleInterop": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
],
|
||||
"paths": {
|
||||
"@angular/*": [
|
||||
|
||||
"node_modules/@angular/*"
|
||||
|
||||
"node_modules/@angular/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -33,7 +27,6 @@
|
||||
"compilationMode": "partial"
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
|
||||
@@ -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/common-map3d'),
|
||||
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
|
||||
});
|
||||
};
|
||||
552
projects/common-map3d/package-lock.json
generated
552
projects/common-map3d/package-lock.json
generated
@@ -11,17 +11,561 @@
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^16.2.12",
|
||||
"@angular/core": "^16.2.12",
|
||||
"cesium": ">=1.82.1",
|
||||
"ngx-openlayers": "file:dist/ngx-openlayers",
|
||||
"@angular/common": "20.3.16",
|
||||
"@angular/core": "20.3.16",
|
||||
"cesium": "^1.97.0",
|
||||
"ol-cesium": ">=2.13.0"
|
||||
}
|
||||
},
|
||||
"../../dist/libs/ng-openlayers": {
|
||||
"version": "18.0.0",
|
||||
"extraneous": true,
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^18.2.3",
|
||||
"@angular/core": "^18.2.3",
|
||||
"ol": "^8.2.0"
|
||||
}
|
||||
},
|
||||
"dist/ng-openlayers": {
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/@angular/common": {
|
||||
"version": "20.3.16",
|
||||
"resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.16.tgz",
|
||||
"integrity": "sha512-GRAziNlntwdnJy3F+8zCOvDdy7id0gITjDnM6P9+n2lXvtDuBLGJKU3DWBbvxcCjtD6JK/g/rEX5fbCxbUHkQQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "20.3.16",
|
||||
"rxjs": "^6.5.3 || ^7.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/core": {
|
||||
"version": "20.3.16",
|
||||
"resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.16.tgz",
|
||||
"integrity": "sha512-KSFPKvOmWWLCJBbEO+CuRUXfecX2FRuO0jNi9c54ptXMOPHlK1lIojUnyXmMNzjdHgRug8ci9qDuftvC2B7MKg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/compiler": "20.3.16",
|
||||
"rxjs": "^6.5.3 || ^7.4.0",
|
||||
"zone.js": "~0.15.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@angular/compiler": {
|
||||
"optional": true
|
||||
},
|
||||
"zone.js": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@cesium/engine": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@cesium/engine/-/engine-11.0.0.tgz",
|
||||
"integrity": "sha512-0z3mJNNly407h3/bAvGoGnjA0ygprkVz32z9x1VNmPXf9AuybKu7Q4wRrChUhC/qsNj3L45kP6KqyDuHSe2bhw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@tweenjs/tween.js": "^25.0.0",
|
||||
"@zip.js/zip.js": "^2.7.34",
|
||||
"autolinker": "^4.0.0",
|
||||
"bitmap-sdf": "^1.0.3",
|
||||
"dompurify": "^3.0.2",
|
||||
"draco3d": "^1.5.1",
|
||||
"earcut": "^3.0.0",
|
||||
"grapheme-splitter": "^1.0.4",
|
||||
"jsep": "^1.3.8",
|
||||
"kdbush": "^4.0.1",
|
||||
"ktx-parse": "^0.7.0",
|
||||
"lerc": "^2.0.0",
|
||||
"mersenne-twister": "^1.1.0",
|
||||
"meshoptimizer": "^0.21.0",
|
||||
"pako": "^2.0.4",
|
||||
"protobufjs": "^7.1.0",
|
||||
"rbush": "^4.0.0",
|
||||
"topojson-client": "^3.1.0",
|
||||
"urijs": "^1.19.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@cesium/widgets": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@cesium/widgets/-/widgets-8.0.0.tgz",
|
||||
"integrity": "sha512-Rnid5BbLBZjwFdbr3lgOwK3fhql/BeEbf5l9ZZE+Zc7V8Fb6wgKM8QmrL+bbJ+BtuiELp+SkNxcF97Ktifxb4g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@cesium/engine": "^11.0.0",
|
||||
"nosleep.js": "^0.12.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@petamoriken/float16": {
|
||||
"version": "3.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.7.tgz",
|
||||
"integrity": "sha512-/Ri4xDDpe12NT6Ex/DRgHzLlobiQXEW/hmG08w1wj/YU7hLemk97c+zHQFp0iZQ9r7YqgLEXZR2sls4HxBf9NA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@protobufjs/base64": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
||||
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@protobufjs/codegen": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
|
||||
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@protobufjs/eventemitter": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
|
||||
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@protobufjs/fetch": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
|
||||
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.1",
|
||||
"@protobufjs/inquire": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/float": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
||||
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@protobufjs/inquire": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
|
||||
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@protobufjs/path": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
||||
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@protobufjs/pool": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
||||
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@protobufjs/utf8": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@tweenjs/tween.js": {
|
||||
"version": "25.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-25.0.0.tgz",
|
||||
"integrity": "sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz",
|
||||
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/rbush": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/rbush/-/rbush-3.0.4.tgz",
|
||||
"integrity": "sha512-knSt9cCW8jj1ZSFcFeBZaX++OucmfPxxHiRwTahZfJlnQsek7O0bazTJHWD2RVj9LEoejUYF2de3/stf+QXcXw==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@zip.js/zip.js": {
|
||||
"version": "2.7.52",
|
||||
"resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.52.tgz",
|
||||
"integrity": "sha512-+5g7FQswvrCHwYKNMd/KFxZSObctLSsQOgqBSi0LzwHo3li9Eh1w5cF5ndjQw9Zbr3ajVnd2+XyiX85gAetx1Q==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"bun": ">=0.7.0",
|
||||
"deno": ">=1.0.0",
|
||||
"node": ">=16.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/autolinker": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/autolinker/-/autolinker-4.0.0.tgz",
|
||||
"integrity": "sha512-fl5Kh6BmEEZx+IWBfEirnRUU5+cOiV0OK7PEt0RBKvJMJ8GaRseIOeDU3FKf4j3CE5HVefcjHmhYPOcaVt0bZw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bitmap-sdf": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/bitmap-sdf/-/bitmap-sdf-1.0.4.tgz",
|
||||
"integrity": "sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/cesium": {
|
||||
"version": "1.121.1",
|
||||
"resolved": "https://registry.npmjs.org/cesium/-/cesium-1.121.1.tgz",
|
||||
"integrity": "sha512-WpdaGFd8qCOHiE9khV0sWWjCMXAX1U9Aou8MzMC/F0Akp6YqcOk4HLk4LLhZKeOjO/Bh27iTIW2mxEZ5+dtCxg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@cesium/engine": "^11.0.0",
|
||||
"@cesium/widgets": "^8.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.0.tgz",
|
||||
"integrity": "sha512-SbtvAMWvASO5TE2QP07jHBMXKafgdZz8Vrsrn96fiL+O92/FN/PLARzUW5sKt013fjAprK2d2iCn2hk2Xb5oow==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
}
|
||||
},
|
||||
"node_modules/color-parse": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/color-parse/-/color-parse-2.0.2.tgz",
|
||||
"integrity": "sha512-eCtOz5w5ttWIUcaKLiktF+DxZO1R9KLNY/xhbV6CkhM7sR3GhVghmt6X6yOnzeaM24po+Z9/S1apbXMwA3Iepw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"color-name": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-rgba": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/color-rgba/-/color-rgba-3.0.0.tgz",
|
||||
"integrity": "sha512-PPwZYkEY3M2THEHHV6Y95sGUie77S7X8v+h1r6LSAPF3/LL2xJ8duUXSrkic31Nzc4odPwHgUbiX/XuTYzQHQg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"color-parse": "^2.0.0",
|
||||
"color-space": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-space": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-space/-/color-space-2.0.1.tgz",
|
||||
"integrity": "sha512-nKqUYlo0vZATVOFHY810BSYjmCARrG7e5R3UE3CQlyjJTvv5kSSmPG1kzm/oDyyqjehM+lW1RnEt9It9GNa5JA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/dompurify": {
|
||||
"version": "3.1.6",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz",
|
||||
"integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/draco3d": {
|
||||
"version": "1.5.7",
|
||||
"resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz",
|
||||
"integrity": "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/earcut": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz",
|
||||
"integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/geotiff": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.1.3.tgz",
|
||||
"integrity": "sha512-PT6uoF5a1+kbC3tHmZSUsLHBp2QJlHasxxxxPW47QIY1VBKpFB+FcDvX+MxER6UzgLQZ0xDzJ9s48B9JbOCTqA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@petamoriken/float16": "^3.4.7",
|
||||
"lerc": "^3.0.0",
|
||||
"pako": "^2.0.4",
|
||||
"parse-headers": "^2.0.2",
|
||||
"quick-lru": "^6.1.1",
|
||||
"web-worker": "^1.2.0",
|
||||
"xml-utils": "^1.0.2",
|
||||
"zstddec": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.19"
|
||||
}
|
||||
},
|
||||
"node_modules/geotiff/node_modules/lerc": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lerc/-/lerc-3.0.0.tgz",
|
||||
"integrity": "sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/grapheme-splitter": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
|
||||
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/jsep": {
|
||||
"version": "1.3.9",
|
||||
"resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.9.tgz",
|
||||
"integrity": "sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/kdbush": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
|
||||
"integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/ktx-parse": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.7.1.tgz",
|
||||
"integrity": "sha512-FeA3g56ksdFNwjXJJsc1CCc7co+AJYDp6ipIp878zZ2bU8kWROatLYf39TQEd4/XRSUvBXovQ8gaVKWPXsCLEQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/lerc": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lerc/-/lerc-2.0.0.tgz",
|
||||
"integrity": "sha512-7qo1Mq8ZNmaR4USHHm615nEW2lPeeWJ3bTyoqFbd35DLx0LUH7C6ptt5FDCTAlbIzs3+WKrk5SkJvw8AFDE2hg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
|
||||
"integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/mersenne-twister": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mersenne-twister/-/mersenne-twister-1.1.0.tgz",
|
||||
"integrity": "sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/meshoptimizer": {
|
||||
"version": "0.21.0",
|
||||
"resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.21.0.tgz",
|
||||
"integrity": "sha512-WabtlpnK/GgD0GMwYd1fBTfYHf4MIcQPEg6dt7y4GuDcY51RzLSkSNE8ZogD7U3Vs2/fIf4z89TOLpA80EOnhg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/nosleep.js": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/nosleep.js/-/nosleep.js-0.12.0.tgz",
|
||||
"integrity": "sha512-9d1HbpKLh3sdWlhXMhU6MMH+wQzKkrgfRkYV0EBdvt99YJfj0ilCJrWRDYG2130Tm4GXbEoTCx5b34JSaP+HhA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/ol": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ol/-/ol-10.1.0.tgz",
|
||||
"integrity": "sha512-/efepydpzhFoeczA9KAN5t7G0WpFhP46ZXEfSl6JbZ7ipQZ2axpkYB2qt0qcOUlPFYMt7/XQFApH652KB08tTg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/rbush": "^3.0.3",
|
||||
"color-rgba": "^3.0.0",
|
||||
"color-space": "^2.0.1",
|
||||
"earcut": "^3.0.0",
|
||||
"geotiff": "^2.0.7",
|
||||
"pbf": "4.0.1",
|
||||
"rbush": "^4.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/openlayers"
|
||||
}
|
||||
},
|
||||
"node_modules/ol-cesium": {
|
||||
"version": "2.17.0",
|
||||
"resolved": "https://registry.npmjs.org/ol-cesium/-/ol-cesium-2.17.0.tgz",
|
||||
"integrity": "sha512-XaMXjQYuq2eMPAgAx2e1wjN4I4QwfmPC+9YgU4xoMCj/MBj8oDQusyloQ4TaovypqbZg+0jJDDSZc7BhXckBwA==",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"cesium": ">= 1.62.0",
|
||||
"ol": ">= 6.0.1 || 7 || 8"
|
||||
}
|
||||
},
|
||||
"node_modules/pako": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
||||
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/parse-headers": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz",
|
||||
"integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/pbf": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz",
|
||||
"integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"resolve-protobuf-schema": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"pbf": "bin/pbf"
|
||||
}
|
||||
},
|
||||
"node_modules/protobufjs": {
|
||||
"version": "7.4.0",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz",
|
||||
"integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==",
|
||||
"hasInstallScript": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.2",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
"@protobufjs/codegen": "^2.0.4",
|
||||
"@protobufjs/eventemitter": "^1.1.0",
|
||||
"@protobufjs/fetch": "^1.1.0",
|
||||
"@protobufjs/float": "^1.0.2",
|
||||
"@protobufjs/inquire": "^1.1.0",
|
||||
"@protobufjs/path": "^1.1.2",
|
||||
"@protobufjs/pool": "^1.1.0",
|
||||
"@protobufjs/utf8": "^1.1.0",
|
||||
"@types/node": ">=13.7.0",
|
||||
"long": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/protocol-buffers-schema": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
|
||||
"integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/quick-lru": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz",
|
||||
"integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/quickselect": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz",
|
||||
"integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/rbush": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rbush/-/rbush-4.0.1.tgz",
|
||||
"integrity": "sha512-IP0UpfeWQujYC8Jg162rMNc01Rf0gWMMAb2Uxus/Q0qOFw4lCcq6ZnQEZwUoJqWyUGJ9th7JjwI4yIWo+uvoAQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"quickselect": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-protobuf-schema": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
|
||||
"integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"protocol-buffers-schema": "^3.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs": {
|
||||
"version": "7.8.2",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
|
||||
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/topojson-client": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz",
|
||||
"integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"commander": "2"
|
||||
},
|
||||
"bin": {
|
||||
"topo2geo": "bin/topo2geo",
|
||||
"topomerge": "bin/topomerge",
|
||||
"topoquantize": "bin/topoquantize"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
|
||||
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/urijs": {
|
||||
"version": "1.19.11",
|
||||
"resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz",
|
||||
"integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/web-worker": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz",
|
||||
"integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/xml-utils": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.10.1.tgz",
|
||||
"integrity": "sha512-Dn6vJ1Z9v1tepSjvnCpwk5QqwIPcEFKdgnjqfYOABv1ngSofuAhtlugcUC3ehS1OHdgDWSG6C5mvj+Qm15udTQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/zstddec": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.1.0.tgz",
|
||||
"integrity": "sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
"publishConfig": {
|
||||
"registry": "https://repository.akkerweb.nl/repository/npm-hosted/"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^16.2.12",
|
||||
"@angular/core": "^16.2.12",
|
||||
"ngx-openlayers": "file:dist/ngx-openlayers",
|
||||
"cesium": ">=1.82.1",
|
||||
"ol-cesium": ">=2.13.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "21.1.0",
|
||||
"@angular/core": "21.1.0",
|
||||
"cesium": "^1.97.0",
|
||||
"ol-cesium": ">=2.13.0"
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { AppCommonModule } from '@farmmaps/common';
|
||||
import { AppCommonMapModule } from '@farmmaps/common-map';
|
||||
import { AngularOpenlayersModule } from '@farmmaps/ng-openlayers';
|
||||
import { Switch2D3DComponent } from './components/olcs/switch2d3d/switch2d3d.component';
|
||||
import { AppCommonModule} from '@farmmaps/common';
|
||||
import { AppCommonMapModule} from '@farmmaps/common-map';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [Switch2D3DComponent],
|
||||
imports: [
|
||||
AppCommonModule,
|
||||
AppCommonMapModule
|
||||
AppCommonMapModule,
|
||||
AngularOpenlayersModule,
|
||||
],
|
||||
exports: [Switch2D3DComponent]
|
||||
})
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { Component, OnInit,Input,Host } from '@angular/core';
|
||||
import { Interaction} from 'ol/interaction';
|
||||
import { MapComponent } from 'ngx-openlayers';
|
||||
import { MapComponent } from '@farmmaps/ng-openlayers';
|
||||
import OLCesium from 'olcs/OLCesium';
|
||||
import RasterSynchronizer from 'olcs/RasterSynchronizer';
|
||||
import VectorSynchronizer from 'olcs/VectorSynchronizer';
|
||||
import { mapReducers,mapActions } from '@farmmaps/common-map';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map3d-switch2d3d',
|
||||
templateUrl: './switch2d3d.component.html',
|
||||
styleUrls: ['./switch2d3d.component.scss']
|
||||
@Component({
|
||||
selector: 'fm-map3d-switch2d3d',
|
||||
templateUrl: './switch2d3d.component.html',
|
||||
styleUrls: ['./switch2d3d.component.scss'],
|
||||
standalone: false
|
||||
})
|
||||
export class Switch2D3DComponent {
|
||||
|
||||
@@ -49,7 +50,11 @@ export class Switch2D3DComponent {
|
||||
this.interactions=[];
|
||||
this.map.instance.getInteractions().forEach((i) => {
|
||||
if(i.getActive()) {
|
||||
this.interactions.push(i);
|
||||
// AW-6241 TODO How to fix?
|
||||
// error TS2345: Argument of type 'import("C:/Project/Farmmaps/FarmMapsLib/node_modules/ol/interaction/Interaction").default'
|
||||
// is not assignable to parameter of type 'import("C:/Project/Farmmaps/FarmMapsLib/projects/common-map3d/node_modules/ol/interaction/Interaction").default'.
|
||||
// Line below commented out
|
||||
// this.interactions.push(i);
|
||||
i.setActive(false);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting(), {
|
||||
teardown: { destroyAfterEach: false }
|
||||
}
|
||||
);
|
||||
@@ -4,7 +4,7 @@
|
||||
"outDir": "../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"moduleResolution": "bundler",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
@@ -13,15 +13,9 @@
|
||||
"importHelpers": true,
|
||||
"esModuleInterop": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
],
|
||||
"paths": {
|
||||
"@angular/*": [
|
||||
|
||||
"node_modules/@angular/*"
|
||||
|
||||
"node_modules/@angular/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -34,7 +28,6 @@
|
||||
"compilationMode": "partial"
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"outDir": "../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"moduleResolution": "bundler",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
@@ -13,15 +13,9 @@
|
||||
"importHelpers": true,
|
||||
"esModuleInterop": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
],
|
||||
"paths": {
|
||||
"@angular/*": [
|
||||
|
||||
"node_modules/@angular/*"
|
||||
|
||||
"node_modules/@angular/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -34,7 +28,6 @@
|
||||
"compilationMode": "partial"
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
|
||||
@@ -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/common'),
|
||||
reports: ['html', 'lcovonly'],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
||||
2390
projects/common/package-lock.json
generated
2390
projects/common/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"name": "@farmmaps/common",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.0",
|
||||
"publishConfig": {
|
||||
"registry": "https://repository.akkerweb.nl/repository/npm-hosted/"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ng-bootstrap/ng-bootstrap": ">=15.0.0",
|
||||
"@angular/common": "^16.2.12",
|
||||
"@angular/core": "^16.2.12",
|
||||
"@angular/forms": "^16.2.12",
|
||||
"@ngrx/effects": "^16",
|
||||
"@ngrx/router-store": "^16",
|
||||
"@ngrx/store": "^16",
|
||||
"tassign": ">1.0.0",
|
||||
"bootstrap": "^5.2.0",
|
||||
"@microsoft/signalr": ">3.1.3",
|
||||
"ngx-uploadx": "^5.2.0",
|
||||
"angular-oauth2-oidc": "^13",
|
||||
"@ng-bootstrap/ng-bootstrap": "^20.0.0",
|
||||
"@angular/common": "21.1.0",
|
||||
"@angular/core": "21.1.0",
|
||||
"@angular/forms": "21.1.0",
|
||||
"@ngrx/effects": "21.0.1",
|
||||
"@ngrx/router-store": "21.0.1",
|
||||
"@ngrx/store": "21.0.1",
|
||||
"tassign": "^1.0.0",
|
||||
"bootstrap": "^5.3.3",
|
||||
"@microsoft/signalr": "10.0.0",
|
||||
"ngx-uploadx": "7.0.1",
|
||||
"angular-oauth2-oidc": "20.0.2",
|
||||
"moment": "^2.29.4",
|
||||
"ngx-avatars": "1.5.0",
|
||||
"ngx-image-cropper": ">7.2.1",
|
||||
"ngx-clipboard": ">15.1.0"
|
||||
"ngx-avatars": "1.10.1",
|
||||
"ngx-image-cropper": "^7.0.0",
|
||||
"ngx-clipboard": "^16.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,8 @@ export const TOGGLENOTIFICATIONMENU = '[AppCommon] ToggleNotificationMenu';
|
||||
|
||||
export const TOGGLEHELPMENU = '[AppCommon] ToggleHelpMenu';
|
||||
|
||||
export const TOGGLESETTINGMENU = '[AppCommon] ToggleSettingMenu';
|
||||
|
||||
export const SETMENUVISIBLE = '[AppCommon] SetMenuVisible';
|
||||
|
||||
export const ONLINE = '[AppCommon] Online';
|
||||
@@ -81,6 +83,11 @@ export const SETPAGEMODE = '[AppCommon] SetPageMode';
|
||||
|
||||
export const SETUNREADNOTIFICATIONS = '[AppCommon] SetUnreadNotifications';
|
||||
|
||||
export const SWITCHLANGUAGE = '[AppCommon] SwitchLanguage';
|
||||
|
||||
export const SETSETTINGMENUBACKGROUNDCOLOR = '[AppCommon] SetSettingMenuBackgroundColor';
|
||||
|
||||
|
||||
export class InitUser implements Action {
|
||||
readonly type = INITUSER;
|
||||
|
||||
@@ -332,6 +339,12 @@ export class ToggleHelpMenu implements Action {
|
||||
constructor() { }
|
||||
}
|
||||
|
||||
export class ToggleSettingMenu implements Action {
|
||||
readonly type = TOGGLESETTINGMENU;
|
||||
|
||||
constructor() { }
|
||||
}
|
||||
|
||||
export class SetMenuVisible implements Action {
|
||||
readonly type = SETMENUVISIBLE;
|
||||
|
||||
@@ -363,6 +376,17 @@ export class SetUnreadNotifications implements Action {
|
||||
|
||||
}
|
||||
|
||||
export class SwitchLanguage implements Action {
|
||||
readonly type = SWITCHLANGUAGE;
|
||||
|
||||
constructor(public locale:string) { }
|
||||
}
|
||||
|
||||
export class SetSettingMenuBackgroundColor implements Action {
|
||||
readonly type = SETSETTINGMENUBACKGROUNDCOLOR;
|
||||
|
||||
constructor(public color:string) { }
|
||||
}
|
||||
|
||||
export type Actions = OpenModal
|
||||
| InitRoot
|
||||
@@ -408,7 +432,10 @@ export type Actions = OpenModal
|
||||
| ToggleAppMenu
|
||||
| ToggleNotificationMenu
|
||||
| ToggleHelpMenu
|
||||
| ToggleSettingMenu
|
||||
| NotificationEvent
|
||||
| SetUnreadNotifications;
|
||||
| SetUnreadNotifications
|
||||
| SwitchLanguage
|
||||
| SetSettingMenuBackgroundColor;
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user