FarmMapsLib/projects/common-map/src/fm-map/effects/map.effects.ts

305 lines
11 KiB
TypeScript
Raw Normal View History

import { Injectable } from '@angular/core';
import { Store, Action } from '@ngrx/store';
import { Effect, Actions,ofType } from '@ngrx/effects';
2020-10-28 12:31:12 +00:00
import { EMPTY, Observable , of } from 'rxjs';
import { withLatestFrom, switchMap, map, catchError, mergeMap } from 'rxjs/operators';
2019-12-11 09:29:47 +00:00
import {GeoJSON,WKT} from 'ol/format';
import {Feature} from 'ol';
2020-04-21 11:22:54 +00:00
import { getCenter,createEmpty,extend } from 'ol/extent';
import {Point} from 'ol/geom'
import * as mapActions from '../actions/map.actions';
import * as mapReducers from '../reducers/map.reducer';
import {commonReducers} from '@farmmaps/common';
import {commonActions} from '@farmmaps/common';
2020-02-12 19:38:14 +00:00
import { IItem } from '@farmmaps/common';
import { FolderService, ItemService } from '@farmmaps/common';
import { tassign } from 'tassign';
2020-02-12 19:38:14 +00:00
import {FeatureIconService} from '../services/feature-icon.service';
import * as style from 'ol/style';
2020-04-22 10:34:07 +00:00
import { ItemTypeService,IQueryState } from '@farmmaps/common';
2020-03-22 19:08:53 +00:00
2020-02-12 19:38:14 +00:00
@Injectable()
export class MapEffects {
2019-12-11 09:29:47 +00:00
private _geojsonFormat: GeoJSON;
private _wktFormat: WKT;
private toPointFeature(updateEvent:commonActions.DeviceUpdateEvent): Feature {
var f = this._wktFormat.readFeature(updateEvent.attributes["geometry"],{
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
});
f.setId(updateEvent.itemCode);
var centroid = getCenter(f.getGeometry().getExtent());
f.setGeometry(new Point(centroid));
return f;
}
@Effect()
init$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.INIT),
withLatestFrom(this.store$.select(commonReducers.selectGetRootItems)),
switchMap(([action, rootItems]) => {
2020-02-12 19:38:14 +00:00
let actions=[];
for (let rootItem of rootItems) {
2020-02-12 19:38:14 +00:00
if (rootItem.itemType == "UPLOADS_FOLDER") actions.push(new mapActions.SetParent(rootItem.code));
}
2020-02-12 19:38:14 +00:00
// 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")
}),
2020-02-12 19:38:14 +00:00
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)'
})
})));
2020-02-12 19:38:14 +00:00
return actions;
}
));
@Effect()
initBaseLayers$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.INIT),
withLatestFrom(this.store$.select(mapReducers.selectGetProjection)),
map(([action, projection]) => new mapActions.LoadBaseLayers(projection)));
@Effect()
loadBaseLayers$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.LOADBASELAYERS),
switchMap((action: mapActions.LoadBaseLayers) => {
return this.itemService$.getItemList("vnd.farmmaps.itemtype.layer", { "isBaseLayer": true }).pipe(
map((items: IItem[]) => new mapActions.LoadBaseLayersSuccess(items)),
catchError(error => of(new commonActions.Fail(error))));
}));
@Effect()
startSearch$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.STARTSEARCH),
2020-10-28 12:31:12 +00:00
switchMap((action) => {
2020-04-22 06:59:04 +00:00
let a = action as mapActions.StartSearch;
var startDate = a.queryState.startDate;
var endDate = a.queryState.endDate;
var newAction:Observable<Action>;
2020-04-22 06:59:04 +00:00
if (a.queryState.itemCode || a.queryState.parentCode || a.queryState.itemType || a.queryState.query || a.queryState.tags) {
newAction= this.itemService$.getFeatures(a.queryState.bbox, "EPSG:3857", a.queryState.query, a.queryState.tags, startDate, endDate, a.queryState.itemType, a.queryState.parentCode).pipe(
switchMap((features: any) => {
for (let f of features.features) {
if (f.properties && f.properties["code"]) {
f.id = f.properties["code"];
}
}
2020-10-28 12:31:12 +00:00
return of(new mapActions.StartSearchSuccess(this._geojsonFormat.readFeatures(features), a.queryState));
}
),
catchError(error => of(new commonActions.Fail(error))));
} else {
return [];
}
return newAction;
}));
@Effect()
2020-04-21 11:22:54 +00:00
zoomToExtent$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.STARTSEARCHSUCCESS),
mergeMap((action: mapActions.StartSearchSuccess) => {
2020-04-21 11:22:54 +00:00
let actions =[];
actions.push(new commonActions.SetMenuVisible(false));
let extent = createEmpty();
if (!action.query.bboxFilter) {
2020-04-21 11:22:54 +00:00
if (extent) {
for (let f of action.features) {
extend(extent, (f as Feature).getGeometry().getExtent());
}
2020-09-29 12:56:23 +00:00
if(action.features && action.features.length >0) {
actions.push(new mapActions.SetExtent(extent));
}
}
2020-04-21 11:22:54 +00:00
}
return actions;
}));
@Effect()
hideMenu$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.STARTSEARCHSUCCESS),
mergeMap((action: mapActions.StartSearchSuccess) => {
return of(new commonActions.SetMenuVisible(false));
}));
@Effect()
selectItem$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.SELECTITEM),
withLatestFrom(this.store$.select(mapReducers.selectGetSelectedItem)),
2020-10-28 12:31:12 +00:00
switchMap(([action, selectedItem]) => {
let a = action as mapActions.SelectItem;
let itemCode = selectedItem ? selectedItem.code : "";
2020-10-28 12:31:12 +00:00
if (a.itemCode != itemCode) {
return this.itemService$.getItem(a.itemCode).pipe(
switchMap(child => {
return this.itemService$.getItem(child.parentCode)
.pipe(map(parent => {
return {child, parent};
}),catchError(() => { let parent:IItem = null;return of({child,parent})})
);
}),
map(data => new mapActions.SelectItemSuccess(data.child, data.parent)),
catchError(error => of(new commonActions.Fail(error))))
} else {
return [];
}
}
));
@Effect()
selectItemSuccess$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.SELECTITEMSUCCESS),
switchMap((action:mapActions.SelectItemSuccess) => {
return this.itemService$.getFeature(action.item.code, "EPSG:3857").pipe(
2019-12-11 09:29:47 +00:00
map((feature: any) => {
let f = this._geojsonFormat.readFeature(feature);
f.setId(action.item.code);
return new mapActions.AddFeatureSuccess(f );
}),
catchError(error => of(new commonActions.Fail(error))));
}
));
2020-02-27 16:59:00 +00:00
@Effect()
selectItemSuccessTemporal$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.SELECTITEMSUCCESS),
switchMap((action:mapActions.SelectItemSuccess) => {
if(action.item.itemType == "vnd.farmmaps.itemtype.temporal") {
return this.itemService$.getChildItemList(action.item.code,null).pipe(
2020-03-03 09:21:24 +00:00
map(items => new mapActions.SelectTemporalItemsSuccess(
items.sort((a, b) =>
2020-07-07 07:24:45 +00:00
-(Date.parse(b.dataDate) - Date.parse(a.dataDate))
2020-03-03 09:21:24 +00:00
)
)),
2020-02-27 16:59:00 +00:00
catchError(error => of(new commonActions.Fail(error))));
} else {
return [];
}
2020-02-27 16:59:00 +00:00
}
));
@Effect()
uploadedItemClick$: Observable<Action> = this.actions$.pipe(
ofType(commonActions.UPLOADEDFILECLICK),
switchMap((action: commonActions.UploadedFileClick) => of(new mapActions.DoQuery(tassign(mapReducers.initialState.query, {itemCode:action.itemCode})))
));
@Effect()
featureUpdate$: Observable<Action> = this.actions$.pipe(
2019-12-11 09:29:47 +00:00
ofType(commonActions.DEVICEUPDATEEVENT),
withLatestFrom(this.store$.select(mapReducers.selectGetFeatures)),
mergeMap(([action, features]) => {
2019-12-11 09:29:47 +00:00
let deviceUpdateEventAction = action as commonActions.DeviceUpdateEvent;
var feature: Feature = null;
for (let f of features) {
2019-12-11 09:29:47 +00:00
if (f.getId() == deviceUpdateEventAction.itemCode) {
feature = f;
break;
}
}
if (feature) {
return of(new mapActions.UpdateFeatureSuccess(this.toPointFeature(deviceUpdateEventAction)));
} else {
return [];
}
}));
@Effect()
itemUpdate$: Observable<Action> = this.actions$.pipe(
ofType(commonActions.ITEMCHANGEDEVENT),
withLatestFrom(this.store$.select(mapReducers.selectGetSelectedItem)),
mergeMap(([action, selectedItem]) => {
let itemChangedAction = action as commonActions.ItemChangedEvent;
if (selectedItem && selectedItem.code == itemChangedAction.itemCode) {
return this.itemService$.getItem(itemChangedAction.itemCode).pipe(
switchMap(child => {
return this.itemService$.getItem(child.parentCode)
.pipe(map(parent => {
return {child, parent};
})
);
}),
map(data => new mapActions.SelectItemSuccess(data.child, data.parent)),
catchError(error => of(new commonActions.Fail(error))));
} else {
return [];
}
}));
2020-04-21 10:31:20 +00:00
getActionFromQueryState(queryState:IQueryState, inSearch:boolean):Observable<Action>|[] {
2020-04-22 07:25:10 +00:00
if(!inSearch && (queryState.itemType || queryState.parentCode || queryState.itemCode || queryState.query || queryState.tags)) {
var newAction:Action;
if (queryState.itemCode && queryState.itemCode != "") {
newAction= new mapActions.SelectItem(queryState.itemCode);
2020-04-21 10:31:20 +00:00
} else {
newAction= new mapActions.StartSearch(queryState);
}
2020-10-28 12:31:12 +00:00
2020-04-21 10:31:20 +00:00
} else {
2020-10-28 12:31:12 +00:00
newAction = new mapActions.Clear();
2020-04-21 10:31:20 +00:00
}
2020-10-28 12:31:12 +00:00
return of(newAction);
}
2020-04-21 10:31:20 +00:00
@Effect()
setState$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.SETSTATE),
withLatestFrom(this.store$.select(mapReducers.selectGetInSearch)),
switchMap(([action,inSearch]) => {
2020-04-21 10:31:20 +00:00
let a = action as mapActions.SetState;
return this.getActionFromQueryState(a.queryState,inSearch);
}));
2020-10-28 12:31:12 +00:00
@Effect()
escape$:Observable<Action> = this.actions$.pipe(
ofType(commonActions.ESCAPE),
switchMap((action) => {
let a = action as commonActions.Escape;
if(a.escapeKey) {
return of(new mapActions.Clear());
} else {
return EMPTY;
}
}));
2020-04-16 15:32:02 +00:00
constructor(private actions$: Actions, private store$: Store<mapReducers.State>, private folderService$: FolderService, private itemService$: ItemService,private featureIconService$:FeatureIconService,private itemTypeService$:ItemTypeService) {
2019-12-11 09:29:47 +00:00
this._geojsonFormat = new GeoJSON();
this._wktFormat = new WKT();
2020-10-28 12:31:12 +00:00
}
}