@@ -32,7 +33,7 @@
-
+
diff --git a/projects/common-map/src/fm-map/components/map/map.component.ts b/projects/common-map/src/fm-map/components/map/map.component.ts
index 985f254..b95024b 100644
--- a/projects/common-map/src/fm-map/components/map/map.component.ts
+++ b/projects/common-map/src/fm-map/components/map/map.component.ts
@@ -14,6 +14,7 @@ import { ISelectedFeatures } from '../../models/selected.features';
import { IItemLayer } from '../../models/item.layer';
import { IQueryState } from '../../models/query.state';
import { IPeriodState } from '../../models/period.state';
+import {IStyles} from '../../models/style.cache';
import { IDroppedFile } from '../aol/file-drop-target/file-drop-target.component';
import { IMetaData } from '../meta-data-modal/meta-data-modal.component';
import { StateSerializerService } from '../../services/state-serializer.service';
@@ -74,6 +75,7 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
public baseLayersCollapsed:boolean = true;
public overlayLayersCollapsed: boolean = true;
public extent$: Observable;
+ public styles$:Observable;
@ViewChild('map', { static: false }) map;
constructor(private store: Store,
@@ -146,6 +148,7 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
this.period$ = this.store.select(mapReducers.selectGetPeriod);
this.position$ = this.geolocationService.getCurrentPosition();
this.compassHeading$ = this.deviceorientationService.getCurrentCompassHeading();
+ this.styles$ = this.store.select(mapReducers.selectGetStyles);
this.mapState$.pipe(withLatestFrom(this.queryState$)).subscribe((state) => {
this.replaceUrl(state[0], state[1], true);
diff --git a/projects/common-map/src/fm-map/effects/map.effects.ts b/projects/common-map/src/fm-map/effects/map.effects.ts
index cf35add..1c6facf 100644
--- a/projects/common-map/src/fm-map/effects/map.effects.ts
+++ b/projects/common-map/src/fm-map/effects/map.effects.ts
@@ -19,10 +19,15 @@ import {commonReducers} from '@farmmaps/common';
import {commonActions} from '@farmmaps/common';
-import { IListItem, IItem } from '@farmmaps/common';
+import { IItem } from '@farmmaps/common';
import { FolderService, ItemService } from '@farmmaps/common';
import { tassign } from 'tassign';
+import {FeatureIconService} from '../services/feature-icon.service';
+
+import * as style from 'ol/style';
+
+
@Injectable()
export class MapEffects {
private _geojsonFormat: GeoJSON;
@@ -44,10 +49,41 @@ export class MapEffects {
ofType(mapActions.INIT),
withLatestFrom(this.store$.select(commonReducers.selectGetRootItems)),
switchMap(([action, rootItems]) => {
+ let actions=[];
for (let rootItem of rootItems) {
- if (rootItem.itemType == "UPLOADS_FOLDER") return of(new mapActions.SetParent(rootItem.code));
+ if (rootItem.itemType == "UPLOADS_FOLDER") actions.push(new mapActions.SetParent(rootItem.code));
}
- return [];
+ // initialize default feature styles
+ actions.push(new mapActions.SetStyle('file',new style.Style({
+ image: new style.Icon({
+ anchor: [0.5, 1],
+ scale: 0.05,
+ src: this.featureIconService$.getIconImageDataUrl("fa fa-file-o")
+ }),
+ stroke: new style.Stroke({
+ color: 'red',
+ width: 1
+ }),
+ fill: new style.Fill({
+ color: 'rgba(0, 0, 255, 0.1)'
+ })
+ })));
+ actions.push(new mapActions.SetStyle('selected',new style.Style({
+ image: new style.Icon({
+ anchor: [0.5, 1],
+ scale: 0.08,
+ src: this.featureIconService$.getIconImageDataUrl(null)
+ }),
+ stroke: new style.Stroke({
+ color: 'red',
+ width: 3
+ }),
+ fill: new style.Fill({
+ color: 'rgba(0, 0, 255, 0.1)'
+ })
+ })));
+
+ return actions;
}
));
@@ -231,7 +267,7 @@ export class MapEffects {
return of(newAction);
}));
- constructor(private actions$: Actions, private store$: Store, private folderService$: FolderService, private itemService$: ItemService) {
+ constructor(private actions$: Actions, private store$: Store, private folderService$: FolderService, private itemService$: ItemService,private featureIconService$:FeatureIconService) {
this._geojsonFormat = new GeoJSON();
this._wktFormat = new WKT();
}
diff --git a/projects/common-map/src/fm-map/models/style.cache.ts b/projects/common-map/src/fm-map/models/style.cache.ts
new file mode 100644
index 0000000..babd726
--- /dev/null
+++ b/projects/common-map/src/fm-map/models/style.cache.ts
@@ -0,0 +1,5 @@
+import {Style} from 'ol';
+
+export interface IStyles{
+ [id: string]: Style;
+};
\ No newline at end of file
diff --git a/projects/common-map/src/fm-map/reducers/map.reducer.ts b/projects/common-map/src/fm-map/reducers/map.reducer.ts
index 9374631..f982ef0 100644
--- a/projects/common-map/src/fm-map/reducers/map.reducer.ts
+++ b/projects/common-map/src/fm-map/reducers/map.reducer.ts
@@ -4,6 +4,7 @@ import { IItemLayer,ItemLayer} from '../models/item.layer';
import { IMapState} from '../models/map.state';
import { IQueryState} from '../models/query.state';
import { IPeriodState} from '../models/period.state';
+import { IStyles} from '../models/style.cache';
import * as mapActions from '../actions/map.actions';
import {commonActions} from '@farmmaps/common';
import { createSelector, createFeatureSelector } from '@ngrx/store';
@@ -51,7 +52,8 @@ export interface State {
selectedItemLayer: IItemLayer,
projection: string,
selectedBaseLayer: IItemLayer,
- selectedOverlayLayer: IItemLayer
+ selectedOverlayLayer: IItemLayer,
+ styles:IStyles
}
export const initialState: State = {
@@ -84,7 +86,8 @@ export const initialState: State = {
projection: "EPSG:3857",
selectedBaseLayer: null,
selectedOverlayLayer: null,
- selectedItemLayer: null
+ selectedItemLayer: null,
+ styles: {}
}
export function reducer(state = initialState, action: mapActions.Actions | commonActions.Actions | RouterNavigationAction): State {
@@ -310,6 +313,12 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
return tassign(state, {});
}
}
+ case mapActions.SETSTYLE:{
+ let a = action as mapActions.SetStyle;
+ let styles = tassign(state.styles);
+ styles[a.itemType] = a.style;
+ return tassign(state,{styles:styles});
+ }
default: {
return state;
}
@@ -336,6 +345,7 @@ export const getSelectedOverlayLayer = (state: State) => state.selectedOverlayLa
export const getQuery = (state: State) => state.query;
export const getSelectedItemLayer = (state: State) => state.selectedItemLayer;
export const getPeriod = (state:State) => state.period;
+export const getStyles = (state:State) => state.styles;
export const selectMapState = createFeatureSelector(MODULE_NAME);
export const selectGetMapState= createSelector(selectMapState, getMapState);
@@ -358,5 +368,6 @@ export const selectGetSelectedOverlayLayer = createSelector(selectMapState, getS
export const selectGetQuery = createSelector(selectMapState, getQuery);
export const selectGetSelectedItemLayer = createSelector(selectMapState, getSelectedItemLayer);
export const selectGetPeriod = createSelector(selectMapState, getPeriod);
+export const selectGetStyles = createSelector(selectMapState, getStyles);
diff --git a/projects/common-map/src/fm-map/services/feature-icon.service.ts b/projects/common-map/src/fm-map/services/feature-icon.service.ts
new file mode 100644
index 0000000..70a5a17
--- /dev/null
+++ b/projects/common-map/src/fm-map/services/feature-icon.service.ts
@@ -0,0 +1,41 @@
+import { Injectable} from '@angular/core';
+import { Feature } from 'ol';
+import { Point } from 'ol/geom';
+import * as extent from 'ol/extent';
+
+
+@Injectable()
+export class FeatureIconService {
+
+ getIconImageDataUrl(iconClass:string, backgroundColor: string = "#c80a6e",color:string = "#ffffff"): string {
+ var canvas = document.createElement('canvas');
+ canvas.width = 365;
+ canvas.height = 560;
+ var ctx = canvas.getContext('2d');
+ ctx.lineWidth = 6;
+ ctx.fillStyle = backgroundColor;
+ ctx.strokeStyle = "#000000";
+ var path = new Path2D("m182.9 551.7c0 0.1 0.2 0.3 0.2 0.3s175.2-269 175.2-357.4c0-130.1-88.8-186.7-175.4-186.9-86.6 0.2-175.4 56.8-175.4 186.9 0 88.4 175.3 357.4 175.3 357.4z");
+ ctx.fill(path)
+
+ var iconCharacter = "";
+ if (iconClass != null) {
+ var element = document.createElement("i");
+ element.style.display = "none";
+ element.className = iconClass;
+ document.body.appendChild(element);
+ iconCharacter = getComputedStyle(element, "::before").content.replace(/"/g, '');
+ let iconFont = "200px " +getComputedStyle(element, "::before").fontFamily
+ document.body.removeChild(element);
+ ctx.strokeStyle = color;
+ ctx.fillStyle = color;
+ ctx.lineWidth = 15;
+ ctx.font = iconFont;
+ var ts = ctx.measureText(iconCharacter);
+ ctx.fillText(iconCharacter, 182.9 - (ts.width / 2), 250);
+ ctx.strokeText(iconCharacter, 182.9 - (ts.width / 2), 250);
+ }
+
+ return canvas.toDataURL();
+ }
+}
\ No newline at end of file
diff --git a/projects/common/src/fm/services/itemtype.service.ts b/projects/common/src/fm/services/itemtype.service.ts
index 426ea45..f81f1ad 100644
--- a/projects/common/src/fm/services/itemtype.service.ts
+++ b/projects/common/src/fm/services/itemtype.service.ts
@@ -4,9 +4,7 @@ import {IItem} from '../models/item'
import {AppConfig} from '../shared/app.config';
import {HttpClient, HttpXhrBackend} from '@angular/common/http';
-@Injectable({
- providedIn: 'root',
-})
+@Injectable()
export class ItemTypeService {
public itemTypes: IItemTypes;
private httpClient: HttpClient;
@@ -15,10 +13,6 @@ export class ItemTypeService {
this.httpClient = new HttpClient(xhrBackend);
}
- // itemService.getItemTypes().subscribe((itemTypes) => {
- // this.itemTypes = itemTypes;
- // });
-
getIcon(itemType: string) {
var icon = "fa fa-file-o";
if (this.itemTypes[itemType]) icon = this.itemTypes[itemType].icon;
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 9a5b5d9..b5fc7c0 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -21,6 +21,7 @@ import { MenuComponent } from './menu/menu.component';
import {RegisterDeviceComponent} from './registerdevice/registerdevice.component';
import { SecureOAuthStorage} from '@farmmaps/common';
import { OAuthStorage } from 'angular-oauth2-oidc';
+import {Id4AuthconfigFactory} from './id4AuthconfigFactory';
export const BOOTSTRAP_EFFECTS = new InjectionToken('Bootstrap Effects');
diff --git a/src/app/id4AuthconfigFactory.ts b/src/app/id4AuthconfigFactory.ts
new file mode 100644
index 0000000..e9776e4
--- /dev/null
+++ b/src/app/id4AuthconfigFactory.ts
@@ -0,0 +1,21 @@
+import { IAuthconfigFactory, AppConfig } from '@farmmaps/common';
+import { AuthConfig } from 'angular-oauth2-oidc';
+
+export class Id4AuthconfigFactory implements IAuthconfigFactory {
+ constructor() {
+
+ }
+
+ getAuthConfig(appConfig: AppConfig): AuthConfig {
+ let authConfig: AuthConfig = new AuthConfig();
+ authConfig.issuer = appConfig.getConfig("issuer");
+ authConfig.redirectUri = window.location.origin + "/cb";
+ authConfig.clientId = appConfig.getConfig("clientId");
+ authConfig.customQueryParams = { audience: appConfig.getConfig("audience") };
+ authConfig.scope = "api offline_access";
+ authConfig.disableAtHashCheck = true;
+ authConfig.responseType = "code";
+ authConfig.requireHttps = appConfig.getConfig("requireHttps");
+ return authConfig;
+ }
+}