diff --git a/angular.json b/angular.json index c408c6a..cdd014c 100644 --- a/angular.json +++ b/angular.json @@ -19,12 +19,28 @@ "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.app.json", "assets": [ - "src/favicon.ico", - "src/assets", + { + "glob": "**/*", + "input":"src/assets/images", + "output":"/images" + }, + { + "glob": "silent-refresh.html", + "input":"src/assets", + "output":"/" + }, + { + "glob": "favicon.ico", + "input":"src/assets", + "output":"/" + }, "src/configuration.json" ], "styles": [ - "src/styles.css" + "src/styles.css", + "node_modules/bootstrap/dist/css/bootstrap.min.css", + "node_modules/font-awesome/css/font-awesome.min.css", + "fonts/FMIconFont/style.css" ], "scripts": [], "es5BrowserSupport": true diff --git a/fonts/FMIconFont/FMIconFont.svg b/fonts/FMIconFont/FMIconFont.svg new file mode 100644 index 0000000..8181e1a --- /dev/null +++ b/fonts/FMIconFont/FMIconFont.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/fonts/FMIconFont/FMIconFont.ttf b/fonts/FMIconFont/FMIconFont.ttf new file mode 100644 index 0000000..c8b8ea1 Binary files /dev/null and b/fonts/FMIconFont/FMIconFont.ttf differ diff --git a/fonts/FMIconFont/FMIconFont.woff b/fonts/FMIconFont/FMIconFont.woff new file mode 100644 index 0000000..0b0d947 Binary files /dev/null and b/fonts/FMIconFont/FMIconFont.woff differ diff --git a/fonts/FMIconFont/FMIconFont.woff2 b/fonts/FMIconFont/FMIconFont.woff2 new file mode 100644 index 0000000..ebf2f18 Binary files /dev/null and b/fonts/FMIconFont/FMIconFont.woff2 differ diff --git a/fonts/FMIconFont/style.css b/fonts/FMIconFont/style.css new file mode 100644 index 0000000..1cc9b8c --- /dev/null +++ b/fonts/FMIconFont/style.css @@ -0,0 +1,32 @@ +/* font converted using font-converter.net. thank you! */ + +.fm { + display: inline-block; + font-style: normal; + font-variant-ligatures: normal; + font-variant-caps: normal; + font-variant-numeric: normal; + font-variant-east-asian: normal; + font-weight: normal; + font-stretch: normal; + font-size: inherit; + line-height: 1; + font-family: FarmMaps; + text-rendering: auto; +} + +.fm-farm:before { + content: "a"; +} + +.fm-potato:before { + content: "b"; +} + +@font-face { + font-family: "FarmMaps"; + src: url("./FMIconFont.woff") format("woff"), /* Modern Browsers */ + url("./FMIconFont.woff2") format("woff2"); /* Modern Browsers */ + font-weight: normal; + font-style: normal; +} diff --git a/package-lock.json b/package-lock.json index f0a2860..ad28535 100644 --- a/package-lock.json +++ b/package-lock.json @@ -679,6 +679,27 @@ } } }, + "@farmmaps/common-map": { + "version": "file:dist/common-map", + "requires": { + "@farmmaps/common": "0.0.1-prerelease.43", + "ngx-openlayers": "1.0.0-next.9", + "ol": "^5.3.3", + "tslib": "^1.9.0" + }, + "dependencies": { + "@farmmaps/common": { + "version": "0.0.1-prerelease.43", + "resolved": "https://repository.akkerweb.nl/repository/npm-group/@farmmaps/common/-/common-0.0.1-prerelease.43.tgz", + "integrity": "sha512-tV42SIpXAremVLolUEW0ESdYRdyllunbIZgHB3ObsqPJMrI0vgnkIr8LdtSaaYokAGXA3L8n6q3Zi78/hiBgQg==", + "requires": { + "angular-oauth2-oidc": "^5.0.2", + "ngx-uploadx": "^3.1.3", + "tslib": "^1.9.0" + } + } + } + }, "@ng-bootstrap/ng-bootstrap": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-4.2.1.tgz", @@ -1108,6 +1129,15 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "angular-oauth2-oidc": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/angular-oauth2-oidc/-/angular-oauth2-oidc-5.0.2.tgz", + "integrity": "sha512-jtOv4IWEjSFfBHVE4seWGWT/ZfWJ95QJ1JaFhVVGJEF64ibGuPwV3ztwTOUl98QHi/Yg4PXXDAisb31JnIbxBw==", + "requires": { + "jsrsasign": "^8.0.12", + "tslib": "^1.9.0" + } + }, "ansi-align": { "version": "2.0.0", "resolved": "https://repository.akkerweb.nl/repository/npm-group/ansi-align/-/ansi-align-2.0.0.tgz", @@ -3768,6 +3798,11 @@ } } }, + "font-awesome": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", + "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" + }, "for-in": { "version": "1.0.2", "resolved": "https://repository.akkerweb.nl/repository/npm-group/for-in/-/for-in-1.0.2.tgz", @@ -4917,8 +4952,7 @@ "ieee754": { "version": "1.1.13", "resolved": "https://repository.akkerweb.nl/repository/npm-group/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, "iferr": { "version": "0.1.5", @@ -5911,6 +5945,11 @@ "verror": "1.10.0" } }, + "jsrsasign": { + "version": "8.0.12", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-8.0.12.tgz", + "integrity": "sha1-Iqu5ZW00owuVMENnIINeicLlwxY=" + }, "jszip": { "version": "3.2.1", "resolved": "https://repository.akkerweb.nl/repository/npm-group/jszip/-/jszip-3.2.1.tgz", @@ -6917,6 +6956,22 @@ "deepmerge": "^3.2.0" } }, + "ngx-openlayers": { + "version": "1.0.0-next.9", + "resolved": "https://registry.npmjs.org/ngx-openlayers/-/ngx-openlayers-1.0.0-next.9.tgz", + "integrity": "sha512-14UFxJX9oeOXtq+HJCJyXn0sBmYmCqj2AnFtetKk1FsDe8EUMFGIRju8UOFegCr2oEu5JsuRjALcfW7lCe+teg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "ngx-uploadx": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ngx-uploadx/-/ngx-uploadx-3.3.2.tgz", + "integrity": "sha512-gRdXXq2cRU9HE6dj65qay9GV8NRC7n8y5LtMzJWqsfu2k3CHMQxo2TqZwA9/l/PqJ76RoO7sTPy1OenFQ+krkQ==", + "requires": { + "tslib": "^1.9.0" + } + }, "nice-try": { "version": "1.0.5", "resolved": "https://repository.akkerweb.nl/repository/npm-group/nice-try/-/nice-try-1.0.5.tgz", @@ -7277,6 +7332,16 @@ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, + "ol": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/ol/-/ol-5.3.3.tgz", + "integrity": "sha512-7eU4x8YMduNcED1D5wI+AMWDRe7/1HmGfsbV+kFFROI9RNABU/6n4osj6Q3trZbxxKnK2DSRIjIRGwRHT/Z+Ww==", + "requires": { + "pbf": "3.1.0", + "pixelworks": "1.1.0", + "rbush": "2.0.2" + } + }, "on-finished": { "version": "2.3.0", "resolved": "https://repository.akkerweb.nl/repository/npm-group/on-finished/-/on-finished-2.3.0.tgz", @@ -7749,6 +7814,15 @@ "pify": "^3.0.0" } }, + "pbf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.1.0.tgz", + "integrity": "sha512-/hYJmIsTmh7fMkHAWWXJ5b8IKLWdjdlAFb3IHkRBn1XUhIYBChVGfVwmHEAV3UfXTxsP/AKfYTXTS/dCPxJd5w==", + "requires": { + "ieee754": "^1.1.6", + "resolve-protobuf-schema": "^2.0.0" + } + }, "pbkdf2": { "version": "3.0.17", "resolved": "https://repository.akkerweb.nl/repository/npm-group/pbkdf2/-/pbkdf2-3.0.17.tgz", @@ -7788,6 +7862,11 @@ "pinkie": "^2.0.0" } }, + "pixelworks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pixelworks/-/pixelworks-1.1.0.tgz", + "integrity": "sha1-Hwla1I3Ki/ihyCWOAJIDGkTyLKU=" + }, "pkg-dir": { "version": "2.0.0", "resolved": "https://repository.akkerweb.nl/repository/npm-group/pkg-dir/-/pkg-dir-2.0.0.tgz", @@ -7946,6 +8025,11 @@ "retry": "^0.10.0" } }, + "protocol-buffers-schema": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.3.2.tgz", + "integrity": "sha512-Xdayp8sB/mU+sUV4G7ws8xtYMGdQnxbeIfLjyO9TZZRJdztBGhlmbI5x1qcY4TG5hBkIKGnc28i7nXxaugu88w==" + }, "protoduck": { "version": "5.0.1", "resolved": "https://repository.akkerweb.nl/repository/npm-group/protoduck/-/protoduck-5.0.1.tgz", @@ -8175,6 +8259,11 @@ "resolved": "https://repository.akkerweb.nl/repository/npm-group/querystringify/-/querystringify-2.1.1.tgz", "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" }, + "quickselect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-1.1.1.tgz", + "integrity": "sha512-qN0Gqdw4c4KGPsBOQafj6yj/PA6c/L63f6CaZ/DCF/xF4Esu3jVmKLUDYxghFx8Kb/O7y9tI7x2RjTSXwdK1iQ==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://repository.akkerweb.nl/repository/npm-group/randombytes/-/randombytes-2.1.0.tgz", @@ -8230,6 +8319,14 @@ "schema-utils": "^1.0.0" } }, + "rbush": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/rbush/-/rbush-2.0.2.tgz", + "integrity": "sha512-XBOuALcTm+O/H8G90b6pzu6nX6v2zCKiFG4BJho8a+bY6AER6t8uQUZdi5bomQc0AprCWhEGa7ncAbbRap0bRA==", + "requires": { + "quickselect": "^1.0.1" + } + }, "rc": { "version": "1.2.8", "resolved": "https://repository.akkerweb.nl/repository/npm-group/rc/-/rc-1.2.8.tgz", @@ -8541,6 +8638,14 @@ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true }, + "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==", + "requires": { + "protocol-buffers-schema": "^3.3.1" + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://repository.akkerweb.nl/repository/npm-group/resolve-url/-/resolve-url-0.2.1.tgz", diff --git a/package.json b/package.json index 7bfd2bd..9b0cc2c 100644 --- a/package.json +++ b/package.json @@ -21,11 +21,13 @@ "@angular/router": "~7.2.0", "@aspnet/signalr": "^1.1.4", "@farmmaps/common": "file:dist/common", + "@farmmaps/common-map": "file:dist/common-map", "@ng-bootstrap/ng-bootstrap": "^4.2.1", "@ngrx/effects": "^7.2.0", "@ngrx/router-store": "^7.2.0", "@ngrx/store": "^7.2.0", "bootstrap": "^4.3.1", + "font-awesome": "^4.7.0", "core-js": "^2.5.4", "ngrx-store-localstorage": "^8.0.0", "resumablejs": "^1.1.0", diff --git a/projects/common-map/src/lib/common-map.component.ts b/projects/common-map/src/lib/common-map.component.ts deleted file mode 100644 index aab1bfd..0000000 --- a/projects/common-map/src/lib/common-map.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'lib-common-map', - template: ` -

- common-map works! -

- `, - styles: [] -}) -export class CommonMapComponent implements OnInit { - - constructor() { } - - ngOnInit() { - } - -} diff --git a/projects/common-map/src/lib/common-map.module.ts b/projects/common-map/src/lib/common-map.module.ts index 0b6f77d..f6d4bab 100644 --- a/projects/common-map/src/lib/common-map.module.ts +++ b/projects/common-map/src/lib/common-map.module.ts @@ -1,4 +1,4 @@ -import { NgModule } from '@angular/core'; +import { NgModule ,ModuleWithProviders} from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -62,6 +62,7 @@ import { WidgetStatusComponent } from './components/widget-status/widget-status. import { ItemListItemShadowComponent } from './components/item-list-item-shadow/item-list-item-shadow.component'; import { ItemListItemBofekComponent } from './components/item-list-item-bofek/item-list-item-bofek.component'; + export { mapEffects, mapReducer, @@ -171,48 +172,26 @@ export { // Switch2D3DComponent ], entryComponents: [ - // FeatureListComponent, - // FeatureListCroppingschemeComponent, - // FeatureListCropfieldComponent, - // FeatureListFeatureComponent, - // FeatureListFeatureCroppingschemeComponent, - // FeatureListFeatureCropfieldComponent, - // SelectedItemComponent, - // SelectedItemCropfieldComponent, - // SelectedItemGeotiffComponent, - // SelectedItemShapeComponent, - // ItemListComponent, - // ItemListItemComponent, - // ItemWidgetWeatherComponent, - // ItemListItemTemporalComponent, - // ItemListItemHeightComponent, - // ItemListItemTipstarComponent, - // ItemListItemWatBalComponent, - // ItemListItemShadowComponent, - // ItemListItemBofekComponent, + FeatureListComponent, + FeatureListCroppingschemeComponent, + FeatureListCropfieldComponent, + FeatureListFeatureComponent, + FeatureListFeatureCroppingschemeComponent, + FeatureListFeatureCropfieldComponent, + SelectedItemComponent, + SelectedItemCropfieldComponent, + SelectedItemGeotiffComponent, + SelectedItemShapeComponent, + ItemListComponent, + ItemListItemComponent, + ItemWidgetWeatherComponent, + ItemListItemTemporalComponent, + ItemListItemHeightComponent, + ItemListItemTipstarComponent, + ItemListItemWatBalComponent, + ItemListItemShadowComponent, + ItemListItemBofekComponent, ], - // providers: [ - // StateSerializerService, - // GeolocationService, - // { 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: SelectedItemShapeComponent, multi: true }, - // { provide: AbstractItemListItemComponent, useClass: ItemListItemComponent, multi: true }, - // { provide: AbstractItemWidgetComponent, useClass: ItemWidgetWeatherComponent, multi: true }, - // { provide: AbstractItemListItemComponent, useClass: ItemListItemTemporalComponent, multi: true }, - // { provide: AbstractItemListItemComponent, useClass: ItemListItemHeightComponent, multi: true }, - // { provide: AbstractItemListItemComponent, useClass: ItemListItemTipstarComponent, multi: true }, - // { provide: AbstractItemListItemComponent, useClass: ItemListItemWatBalComponent, multi: true }, - // { provide: AbstractItemListItemComponent, useClass: ItemListItemShadowComponent, multi: true }, - // { provide: AbstractItemListItemComponent, useClass: ItemListItemBofekComponent, multi: true }, - // { provide: AbstractItemListComponent, useClass: ItemListComponent, multi: true } - // ], exports: [ ItemVectorSourceComponent, ItemFeaturesSourceComponent, @@ -256,4 +235,33 @@ export { ZoomToExtentComponent ] }) -export class CommonMapModule { } + +export class AppCommonMapModule { + static forRoot(): ModuleWithProviders { + return { + ngModule: AppCommonMapModule, + providers: [ + StateSerializerService, + GeolocationService, + { 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: SelectedItemShapeComponent, multi: true }, + { provide: AbstractItemListItemComponent, useClass: ItemListItemComponent, multi: true }, + { provide: AbstractItemWidgetComponent, useClass: ItemWidgetWeatherComponent, multi: true }, + { provide: AbstractItemListItemComponent, useClass: ItemListItemTemporalComponent, multi: true }, + { provide: AbstractItemListItemComponent, useClass: ItemListItemHeightComponent, multi: true }, + { provide: AbstractItemListItemComponent, useClass: ItemListItemTipstarComponent, multi: true }, + { provide: AbstractItemListItemComponent, useClass: ItemListItemWatBalComponent, multi: true }, + { provide: AbstractItemListItemComponent, useClass: ItemListItemShadowComponent, multi: true }, + { provide: AbstractItemListItemComponent, useClass: ItemListItemBofekComponent, multi: true }, + { provide: AbstractItemListComponent, useClass: ItemListComponent, multi: true } + ] + }; + } +} diff --git a/projects/common-map/src/lib/components/aol/gps-location/gps-location.component.ts b/projects/common-map/src/lib/components/aol/gps-location/gps-location.component.ts index 71f97df..9b09203 100644 --- a/projects/common-map/src/lib/components/aol/gps-location/gps-location.component.ts +++ b/projects/common-map/src/lib/components/aol/gps-location/gps-location.component.ts @@ -30,7 +30,7 @@ export class GpsLocation implements OnInit,OnChanges{ } recalcLocationTolerance() { - this.locTolerancePixels = this.locationTolerance / this.resolution; + this.locTolerancePixels = this.resolution >0? this.locationTolerance / this.resolution:0; } ngOnInit() { diff --git a/projects/common-map/src/lib/components/aol/item-layers/item-layers.component.ts b/projects/common-map/src/lib/components/aol/item-layers/item-layers.component.ts index ee23c41..bbcde72 100644 --- a/projects/common-map/src/lib/components/aol/item-layers/item-layers.component.ts +++ b/projects/common-map/src/lib/components/aol/item-layers/item-layers.component.ts @@ -34,7 +34,7 @@ export class ItemLayersComponent extends LayerGroupComponent implements OnChange constructor(private itemService: ItemService, @Host() private map: MapComponent, public appConfig: AppConfig) { super(map); - this._apiEndPoint = "";//appConfig.getConfig("apiEndPoint"); + this._apiEndPoint = appConfig.getConfig("apiEndPoint"); } private styleCache = {} diff --git a/projects/common-map/src/lib/components/feature-list-feature-cropfield/feature-list-feature-cropfield.component.ts b/projects/common-map/src/lib/components/feature-list-feature-cropfield/feature-list-feature-cropfield.component.ts index 8572b60..b8290eb 100644 --- a/projects/common-map/src/lib/components/feature-list-feature-cropfield/feature-list-feature-cropfield.component.ts +++ b/projects/common-map/src/lib/components/feature-list-feature-cropfield/feature-list-feature-cropfield.component.ts @@ -2,7 +2,7 @@ import { Component, Input, Injectable} from '@angular/core'; import { Feature } from 'ol'; import { Store } from '@ngrx/store'; import * as mapReducers from '../../reducers/map.reducer'; -import { commonReducers,ItemTypeService } from '@farmmaps/common'; +import { commonReducers,ItemTypeService,AppConfig } from '@farmmaps/common'; import { AbstractFeatureListFeatureComponent } from '../feature-list-feature/feature-list-feature.component'; import { ForItemType } from '../for-item/for-itemtype.decorator'; @@ -16,7 +16,7 @@ import { ForItemType } from '../for-item/for-itemtype.decorator'; }) export class FeatureListFeatureCropfieldComponent extends AbstractFeatureListFeatureComponent { - constructor(store: Store, itemTypeService: ItemTypeService) { - super(store, itemTypeService); + constructor(store: Store, itemTypeService: ItemTypeService,config:AppConfig) { + super(store, itemTypeService,config); } } diff --git a/projects/common-map/src/lib/components/feature-list-feature-croppingscheme/feature-list-feature-croppingscheme.component.ts b/projects/common-map/src/lib/components/feature-list-feature-croppingscheme/feature-list-feature-croppingscheme.component.ts index 74c5038..cfc40d9 100644 --- a/projects/common-map/src/lib/components/feature-list-feature-croppingscheme/feature-list-feature-croppingscheme.component.ts +++ b/projects/common-map/src/lib/components/feature-list-feature-croppingscheme/feature-list-feature-croppingscheme.component.ts @@ -2,7 +2,7 @@ import { Component, Input, Injectable} from '@angular/core'; import { Feature } from 'ol'; import { Store } from '@ngrx/store'; import * as mapReducers from '../../reducers/map.reducer'; -import { commonReducers,ItemTypeService } from '@farmmaps/common'; +import { commonReducers,ItemTypeService,AppConfig } from '@farmmaps/common'; import { AbstractFeatureListFeatureComponent } from '../feature-list-feature/feature-list-feature.component'; import { ForItemType } from '../for-item/for-itemtype.decorator'; @@ -16,7 +16,7 @@ import { ForItemType } from '../for-item/for-itemtype.decorator'; }) export class FeatureListFeatureCroppingschemeComponent extends AbstractFeatureListFeatureComponent { - constructor(store: Store, itemTypeService: ItemTypeService) { - super(store, itemTypeService); + constructor(store: Store, itemTypeService: ItemTypeService,config:AppConfig) { + super(store, itemTypeService,config); } } diff --git a/projects/common-map/src/lib/components/feature-list-feature/feature-list-feature.component.html b/projects/common-map/src/lib/components/feature-list-feature/feature-list-feature.component.html index c5d7fc1..5eca85c 100644 --- a/projects/common-map/src/lib/components/feature-list-feature/feature-list-feature.component.html +++ b/projects/common-map/src/lib/components/feature-list-feature/feature-list-feature.component.html @@ -1,6 +1,6 @@
- +
diff --git a/projects/common-map/src/lib/components/feature-list-feature/feature-list-feature.component.ts b/projects/common-map/src/lib/components/feature-list-feature/feature-list-feature.component.ts index a1e8c4f..d8576ff 100644 --- a/projects/common-map/src/lib/components/feature-list-feature/feature-list-feature.component.ts +++ b/projects/common-map/src/lib/components/feature-list-feature/feature-list-feature.component.ts @@ -2,7 +2,7 @@ import { Component, Input, Injectable} from '@angular/core'; import { Feature } from 'ol'; import { Store } from '@ngrx/store'; import * as mapReducers from '../../reducers/map.reducer'; -import { commonReducers,ItemTypeService } from '@farmmaps/common'; +import { commonReducers,ItemTypeService,AppConfig } from '@farmmaps/common'; @@ -10,7 +10,7 @@ import { commonReducers,ItemTypeService } from '@farmmaps/common'; export abstract class AbstractFeatureListFeatureComponent { @Input() feature: Feature - constructor(public store: Store, public itemTypeService: ItemTypeService) { + constructor(public store: Store, public itemTypeService: ItemTypeService,public config:AppConfig) { } } @@ -22,7 +22,7 @@ export abstract class AbstractFeatureListFeatureComponent { }) export class FeatureListFeatureComponent extends AbstractFeatureListFeatureComponent { - constructor(store: Store, itemTypeService: ItemTypeService) { - super(store, itemTypeService); + constructor(store: Store, itemTypeService: ItemTypeService, config:AppConfig) { + super(store, itemTypeService,config); } } diff --git a/projects/common-map/src/lib/components/map/map.component.ts b/projects/common-map/src/lib/components/map/map.component.ts index dcea912..5df667f 100644 --- a/projects/common-map/src/lib/components/map/map.component.ts +++ b/projects/common-map/src/lib/components/map/map.component.ts @@ -225,7 +225,7 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit { replaceUrl(mapState: IMapState, queryState: IQueryState, replace: boolean = true) { //console.log(`Replace url :${mapState.baseLayerCode}`) - this.router.navigate([".", mapState.xCenter.toFixed(5), mapState.yCenter.toFixed(5), mapState.zoom, mapState.rotation.toFixed(2), mapState.baseLayerCode, this.serializeService.serialize(queryState)], { replaceUrl: replace,relativeTo:this.route.parent.parent }); + this.router.navigate([".", mapState.xCenter.toFixed(5), mapState.yCenter.toFixed(5), mapState.zoom, mapState.rotation.toFixed(2), mapState.baseLayerCode, this.serializeService.serialize(queryState)], { replaceUrl: replace,relativeTo:this.route.parent }); } handleOnMoveEnd(event) { @@ -251,8 +251,6 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit { this.store.dispatch(new mapActions.CollapseSearch()); } - - handleOnDownload(event) { } diff --git a/projects/common-map/src/lib/map.component.ts b/projects/common-map/src/lib/map.component.ts new file mode 100644 index 0000000..7b9ba15 --- /dev/null +++ b/projects/common-map/src/lib/map.component.ts @@ -0,0 +1,297 @@ +import { Component, OnInit, OnDestroy, HostListener, Inject, ViewChild, AfterViewInit } from '@angular/core'; +import { Location } from '@angular/common'; +import { Observable, Subject, Subscription,combineLatest, from } from 'rxjs'; +import { debounce, withLatestFrom, first, combineAll } from 'rxjs/operators'; +import { Router, ActivatedRoute, ParamMap, Event } from '@angular/router'; +import { Store } from '@ngrx/store'; +//import { proj,Map } from 'openlayers'; + +// Map +import * as mapReducers from './reducers/map.reducer'; +import * as mapActions from './actions/map.actions'; +import { IMapState,ISelectedFeatures,IItemLayer, ItemLayer,IQueryState,IPeriodState } from './models'; +import { IDroppedFile } from './components/aol/file-drop-target/file-drop-target.component'; +import { IMetaData } from './components/meta-data-modal/meta-data-modal.component'; +import { StateSerializerService } from './services/state-serializer.service'; +import { GeolocationService} from './services/geolocation.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 {Feature} from 'ol'; +import {Extent,createEmpty,extend } from 'ol/extent'; +import {transform} from 'ol/proj'; +import { query } from '@angular/animations'; +import { tassign } from 'tassign'; + + +@Component({ + selector: 'map', + templateUrl: './map.component.html', + styleUrls: ['./map.component.scss'] +}) + +export class MapComponent implements OnInit, OnDestroy,AfterViewInit { + title: string = 'Map'; + public openedModalName: Observable; + public itemTypes: Observable<{ [id: string]: IItemType }>; + public mapState: Observable; + public features: Observable>; + public overlayLayers: Observable>; + public selectedOverlayLayer: Observable; + public selectedItemLayer: Observable; + public baseLayers: Observable>; + public selectedBaseLayer: Observable; + public projection: Observable; + public selectedFeatures: Subject = new Subject(); + public droppedFile: Subject = new Subject(); + private paramSub: Subscription; + private itemTypeSub: Subscription; + private mapStateSub: Subscription; + private queryStateSub: Subscription; + public parentCode: Observable; + public panelVisible: Observable; + public panelCollapsed: Observable; + public selectedFeature: Observable; + public selectedItem: Observable; + public queryState: Observable; + public period: Observable; + public clearEnabled: Observable; + public searchCollapsed: Observable; + public searchMinified: Observable; + public menuVisible: Observable; + public query: Observable; + public position: Observable; + public baseLayersCollapsed:boolean = true; + public overlayLayersCollapsed: boolean = true; + public extent: Observable; + @ViewChild('map') map; + + constructor(private store: Store, private route: ActivatedRoute, private router: Router, private uploadService: ResumableFileUploadService, private serializeService: StateSerializerService, public itemTypeService: ItemTypeService, private location: Location, private geolocationService: GeolocationService ) { + } + + @HostListener('document:keyup', ['$event']) + escapeClose(event: KeyboardEvent) { + let x = event.keyCode; + if (x === 27) { + this.handleCloseModal() + } + } + + handleOpenModal(modalName: string) { + this.store.dispatch(new commonActions.OpenModal(modalName)); + } + + handleCloseModal() { + this.store.dispatch(new commonActions.CloseModal()); + } + + handleFileDropped(droppedFile: IDroppedFile) { + this.uploadService.addFiles(droppedFile.files, droppedFile.event, { parentCode:droppedFile.parentCode, geometry:droppedFile.geometry }); + } + + handleFeaturesSelected(feature: Feature) { + if (feature) { + let newQuery = tassign(mapReducers.initialQueryState, { itemCode: feature.get('code') }); + this.store.dispatch(new mapActions.DoQuery(newQuery)); + } + } + + handleSearch(queryState: IQueryState) { + this.store.dispatch(new mapActions.DoQuery(queryState)); + } + + ngOnInit() { + this.store.dispatch(new mapActions.Init()); + this.selectedFeatures.next({x:0,y:0,features:[]}); + this.mapState = this.store.select(mapReducers.selectGetMapState); + this.parentCode = this.store.select(mapReducers.selectGetParentCode); + this.features = this.store.select(mapReducers.selectGetFeatures); + this.overlayLayers = this.store.select(mapReducers.selectGetOverlayLayers); + this.selectedOverlayLayer = this.store.select(mapReducers.selectGetSelectedOverlayLayer); + this.baseLayers = this.store.select(mapReducers.selectGetBaseLayers); + this.projection = this.store.select(mapReducers.selectGetProjection); + this.selectedBaseLayer = this.store.select(mapReducers.selectGetSelectedBaseLayer); + this.panelVisible = this.store.select(mapReducers.selectGetPanelVisible); + this.panelCollapsed = this.store.select(mapReducers.selectGetPanelCollapsed); + this.selectedFeature = this.store.select(mapReducers.selectGetSelectedFeature); + this.selectedItem = this.store.select(mapReducers.selectGetSelectedItem); + this.queryState = this.store.select(mapReducers.selectGetQueryState); + this.clearEnabled = this.store.select(mapReducers.selectGetClearEnabled); + this.searchCollapsed = this.store.select(mapReducers.selectGetSearchCollapsed); + this.searchMinified = this.store.select(mapReducers.selectGetSearchMinified); + this.menuVisible = this.store.select(mapReducers.selectGetMenuVisible); + this.openedModalName = this.store.select(commonReducers.selectOpenedModalName); + this.query = this.store.select(mapReducers.selectGetQuery); + this.extent = this.store.select(mapReducers.selectGetExtent); + this.selectedFeatures.next(null); + this.selectedItemLayer = this.store.select(mapReducers.selectGetSelectedItemLayer); + this.period = this.store.select(mapReducers.selectGetPeriod); + this.position = this.geolocationService.getCurrentPosition(); + + this.mapState.pipe(withLatestFrom(this.queryState)).subscribe((state) => { + this.replaceUrl(state[0], state[1], true); + }); + this.query.pipe(withLatestFrom(this.mapState)).subscribe((state) => { + this.replaceUrl(state[1], state[0],false); + }); + } + + private stateSetCount: number = 0; + private lastQueryState: string = this.serializeService.serialize(mapReducers.initialQueryState); + private lastMapState: string = ""; + ngAfterViewInit() { + this.paramSub = this.route.paramMap.subscribe((params: ParamMap) => { + //console.log("Param sub"); + var newMapState: IMapState = null; + var newQueryState: IQueryState = null; + var mapStateChanged = false; + var queryStateChanged = false; + if (params.has("xCenter") && params.has("yCenter")) { + let xCenter = parseFloat(params.get("xCenter")); + let yCenter = parseFloat(params.get("yCenter")); + let zoom = parseFloat(params.get("zoom")); + let rotation = parseFloat(params.get("rotation")); + let baseLayer = params.get("baseLayer"); + newMapState = { xCenter: xCenter, yCenter: yCenter, zoom: zoom, rotation: rotation, baseLayerCode: baseLayer } + mapStateChanged = this.lastMapState != JSON.stringify(newMapState) && this.stateSetCount == 0; + this.lastMapState = JSON.stringify(newMapState); + //console.log(`Base layer: ${newMapState.baseLayerCode}`) + } + if (params.has("queryState")) { + let queryState = params.get("queryState"); + newQueryState = tassign(mapReducers.initialQueryState); + if (queryState != "") { + newQueryState = this.serializeService.deserialize(queryState); + } + queryStateChanged = this.lastQueryState != queryState; + this.lastQueryState = queryState; + } + + if (mapStateChanged && queryStateChanged) { + //console.log("Both states"); + this.store.dispatch(new mapActions.SetState(newMapState, newQueryState)); + } else if (mapStateChanged) { + //console.log("Map state"); + this.store.dispatch(new mapActions.SetMapState(newMapState)); + } else if (queryStateChanged) { + //console.log("Query state"); + this.store.dispatch(new mapActions.SetQueryState(newQueryState)); + } + this.stateSetCount += 1; + }); + setTimeout(() => { + this.map.instance.updateSize(); + }, 500); + } + + handleSearchCollapse(event) { + this.store.dispatch(new mapActions.CollapseSearch()); + } + + handleSearchExpand(event) { + this.store.dispatch(new mapActions.ExpandSearch()); + } + + handleToggleMenu(event) { + this.store.dispatch(new mapActions.ToggleMenu()); + } + + handleToggleBaseLayers(event:MouseEvent) { + this.baseLayersCollapsed = !this.baseLayersCollapsed; + event.preventDefault(); + } + + handleToggleOverlayLayers(event: MouseEvent) { + this.overlayLayersCollapsed = !this.overlayLayersCollapsed; + event.preventDefault(); + } + + handlePredefinedQuery(event: MouseEvent, query: any) { + event.preventDefault(); + var queryState = tassign(mapReducers.initialQueryState, query); + this.store.dispatch(new mapActions.DoQuery(queryState)); + } + + handleTrijntjeClick(event: MouseEvent, query: any) { + event.preventDefault(); + var queryState = tassign(mapReducers.initialQueryState, query); + var mapState = JSON.parse(this.lastMapState); + this.router.navigate(["app","trijntje" , mapState.xCenter.toFixed(5), mapState.yCenter.toFixed(5), mapState.zoom, mapState.rotation.toFixed(2), mapState.baseLayerCode, this.serializeService.serialize(queryState)], { replaceUrl: false }); + } + + replaceUrl(mapState: IMapState, queryState: IQueryState, replace: boolean = true) { + //console.log(`Replace url :${mapState.baseLayerCode}`) + this.router.navigate([".", mapState.xCenter.toFixed(5), mapState.yCenter.toFixed(5), mapState.zoom, mapState.rotation.toFixed(2), mapState.baseLayerCode, this.serializeService.serialize(queryState)], { replaceUrl: replace,relativeTo:this.route.parent.parent }); + } + + handleOnMoveEnd(event) { + var map = event.map; + var view = map.getView(); + var rotation = view.getRotation(); + var zoom = view.getZoom(); + var center = transform(view.getCenter(), view.getProjection(), "EPSG:4326"); + var extent = view.calculateExtent(this.map.instance.getSize()); + let mapState: IMapState = { xCenter: center[0], yCenter: center[1], zoom: zoom, rotation: rotation, baseLayerCode: null }; + let state = { mapState: mapState, extent: extent }; + let source = from([state]); + source.pipe(withLatestFrom(this.selectedBaseLayer), withLatestFrom(this.queryState)).subscribe(([[state, baselayer], queryState]) => { + if (mapState && baselayer && queryState) { + let newMapState = tassign(state.mapState, { baseLayerCode: baselayer.item.code }); + this.replaceUrl(newMapState, tassign(queryState, { bbox: queryState.bboxFilter ? state.extent : queryState.bbox })); + this.store.dispatch(new mapActions.SetViewExtent(state.extent)); + } + }); + } + + handleOnMouseDown(event: MouseEvent) { + this.store.dispatch(new mapActions.CollapseSearch()); + } + + + + handleOnDownload(event) { + + } + + handleClearSearch(event) { + this.store.dispatch(new commonActions.Escape(true, false)); + } + + handleOnDelete(itemLayer: IItemLayer) { + this.store.dispatch(new mapActions.RemoveLayer(itemLayer)); + } + + handleOnToggleVisibility(itemLayer: IItemLayer) { + this.store.dispatch(new mapActions.SetVisibility(itemLayer,!itemLayer.visible)); + } + + handleOnSetOpacity(event:{ layer: IItemLayer,opacity:number }) { + this.store.dispatch(new mapActions.SetOpacity(event.layer, event.opacity)); + } + + handleZoomToExtent(itemLayer: IItemLayer) { + var extent = createEmpty(); + extend(extent, itemLayer.layer.getExtent()); + if (extent) { + this.store.dispatch(new mapActions.SetExtent(extent)); + } + } + + handleSelectBaseLayer(itemLayer: IItemLayer) { + this.store.dispatch(new mapActions.SelectBaseLayer(itemLayer)); + } + + handleSelectOverlayLayer(itemLayer: IItemLayer) { + this.store.dispatch(new mapActions.SelectOverlayLayer(itemLayer)); + } + + ngOnDestroy() { + this.paramSub.unsubscribe(); + if (this.itemTypeSub) this.itemTypeSub.unsubscribe(); + if (this.mapStateSub) this.mapStateSub.unsubscribe(); + if (this.queryStateSub) this.queryStateSub.unsubscribe(); } +} diff --git a/projects/common/src/lib/services/itemtype.service.ts b/projects/common/src/lib/services/itemtype.service.ts index 5304bb1..62fed20 100644 --- a/projects/common/src/lib/services/itemtype.service.ts +++ b/projects/common/src/lib/services/itemtype.service.ts @@ -15,7 +15,7 @@ export class ItemTypeService { } getIcon(itemType: string) { - var icon = "fa-file-o"; + var icon = "fa fa-file-o"; if (this.itemTypes[itemType]) icon = this.itemTypes[itemType].icon; return icon; } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 86dee29..ad26c34 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,13 +1,28 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; -import { AuthGuard } from '@farmmaps/common'; +import { AuthGuard,FullScreenGuard } from '@farmmaps/common'; +import { MapComponent} from '@farmmaps/common-map'; import { AppContentComponent} from './app-content.component'; import { AppSidePanelTestComponent } from './app-side-panel-test.component'; const routes = [ - { path: '', canLoad: [AuthGuard], component: AppContentComponent}, - { path: 'sidepanel', canLoad: [AuthGuard], component: AppSidePanelTestComponent} + { + path: '', + redirectTo: 'map', + pathMatch: 'full' + }, + { path: 'sidepanel', canLoad: [AuthGuard], component: AppSidePanelTestComponent}, + { path: 'map', canActivateChild: [AuthGuard],canActivate:[FullScreenGuard], children: [ + { + path: '', + component: MapComponent + }, + { + path: ':xCenter/:yCenter/:zoom/:rotation/:baseLayer/:queryState', + component: MapComponent + } + ]}, ]; @NgModule({ diff --git a/src/app/app.component.css b/src/app/app.component.css deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/app.component.scss b/src/app/app.component.scss new file mode 100644 index 0000000..4394fdc --- /dev/null +++ b/src/app/app.component.scss @@ -0,0 +1,21 @@ +@import "theme.scss"; + +$fa-font-path: "~font-awesome/fonts"; +@import "~bootstrap/scss/bootstrap.scss"; +@import "~font-awesome/scss/font-awesome.scss"; + +:host ::ng-deep .btn:focus { + box-shadow:none; +} + +:host ::ng-deep .input-group > .form-control:focus { + z-index: auto; +} + +:host ::ng-deep .form-control:focus { + box-shadow: none; + border-color: $input-border-color; +} + + + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 3a9178e..eedc897 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', - styleUrls: ['./app.component.css'] + styleUrls: ['./app.component.scss'] }) export class AppComponent { title = 'farmmaps-lib-app'; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 73502dd..7712c5a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -10,6 +10,7 @@ import { AppComponent } from './app.component'; import { AppContentComponent } from './app-content.component'; import { AppSidePanelTestComponent } from './app-side-panel-test.component'; import { AppCommonModule } from '@farmmaps/common'; +import { AppCommonMapModule} from '@farmmaps/common-map'; import {StoreModule, Store} from '@ngrx/store'; import {EffectsModule, EffectSources} from '@ngrx/effects'; @@ -51,6 +52,7 @@ export function provideBootstrapEffects(effects: Type[]) { imports: [ AppRoutingModule, AppCommonModule.forRoot() , + AppCommonMapModule.forRoot(), BrowserModule, StoreModule.forRoot({}), EffectsModule.forRoot([]) diff --git a/src/app/theme.scss b/src/app/theme.scss new file mode 100644 index 0000000..b44a9a8 --- /dev/null +++ b/src/app/theme.scss @@ -0,0 +1,3 @@ +//$theme-colors: ( "primary": #a7ce39, "secondary": #ffc800 ); +//$theme-colors: ( "primary": #a7ce39); + diff --git a/src/favicon.ico b/src/assets/favicon.ico similarity index 100% rename from src/favicon.ico rename to src/assets/favicon.ico diff --git a/src/assets/images/farmmapslogo.png b/src/assets/images/farmmapslogo.png new file mode 100644 index 0000000..428742d Binary files /dev/null and b/src/assets/images/farmmapslogo.png differ diff --git a/src/assets/silent-refresh.html b/src/assets/silent-refresh.html new file mode 100644 index 0000000..e65ce39 --- /dev/null +++ b/src/assets/silent-refresh.html @@ -0,0 +1,7 @@ + + + + + diff --git a/src/configuration.json b/src/configuration.json index 875949d..341b778 100644 --- a/src/configuration.json +++ b/src/configuration.json @@ -1,8 +1,8 @@ { "issuer": "http://accounts.awtest.nl", "clientId": "v1t", - "audience": "http://localhost:8083/,http://awtest.nl/,http://aan.awtest.nl", + "audience": "http://farmmaps.awtest.nl/,http://awtest.nl/,http://aan.awtest.nl", "requireHttps": false, - "apiEndPoint": "http://localhost:8083" + "apiEndPoint": "http://farmmaps.awtest.nl" } \ No newline at end of file diff --git a/src/index.html b/src/index.html index 3d6ee2f..083a46c 100644 --- a/src/index.html +++ b/src/index.html @@ -7,7 +7,6 @@ -