Compare commits
3 Commits
4a64a702e8
...
471a85a428
Author | SHA1 | Date | |
---|---|---|---|
|
471a85a428 | ||
|
bd4be813ae | ||
|
b89072d0c5 |
@ -23,7 +23,7 @@ docker run -t -i --entrypoint /bin/bash -p 4200:4200 node:10.16.0
|
|||||||
Inside the running container
|
Inside the running container
|
||||||
```
|
```
|
||||||
git clone https://git.akkerweb.nl/FarmMaps/FarmMapsLib.git
|
git clone https://git.akkerweb.nl/FarmMaps/FarmMapsLib.git
|
||||||
cd FarmMapslib
|
cd FarmMapsLib
|
||||||
npm config set @farmmaps:registry https://repository.akkerweb.nl/repository/npm-group/
|
npm config set @farmmaps:registry https://repository.akkerweb.nl/repository/npm-group/
|
||||||
npm install -g @angular/cli
|
npm install -g @angular/cli
|
||||||
npm install
|
npm install
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
.head {
|
|
||||||
color: grey;
|
|
||||||
font-weight: bold;
|
|
||||||
/*border-bottom:1px solid black;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.body {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.unit {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dateformat {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
<div class="widget">
|
|
||||||
<div class="d-flex flex-column justify-content-center w-100 h-100">
|
|
||||||
<div class="head h-20 p-1" i18n>Bofek Bodem {{ feature?.bodem }}</div>
|
|
||||||
<div class="body d-flex flex-column h-100 w-100">
|
|
||||||
<small i18n>Periode:{{ feature?.periode }}</small>
|
|
||||||
<small i18n>dmgdry/dmgwet:{{ feature?.dmgdry | number:'0.1-2'}}/{{ feature?.dmgwet | number:'0.1-2'}}</small>
|
|
||||||
<small i18n>dmgind:{{ feature?.dmgind | number:'0.1-2'}}</small>
|
|
||||||
<small i18n>gewas:{{ feature?.gewas}}</small>
|
|
||||||
<small i18n>glg/ghg:{{ feature?.glg}}/{{ feature?.ghg}}</small>
|
|
||||||
<small i18n>station:{{ feature?.station}}</small>
|
|
||||||
<small i18n>hrvpotbio:{{ feature?.hrvpotbio}}</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,42 +0,0 @@
|
|||||||
import { Component, OnInit, Injectable } from '@angular/core';
|
|
||||||
import { Input } from '@angular/core';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import * as mapReducers from '../../reducers/map.reducer';
|
|
||||||
import { commonReducers, ItemTypeService, ItemService, IListItem } from '@farmmaps/common';
|
|
||||||
import { AbstractItemListItemComponent } from '../item-list-item/item-list-item.component'
|
|
||||||
import { ForItemType } from '../for-item/for-itemtype.decorator';
|
|
||||||
import { ForSourceTask } from '../for-item/for-sourcetask.decorator';
|
|
||||||
|
|
||||||
@ForItemType("vnd.farmmaps.itemtype.shape.processed")
|
|
||||||
@ForSourceTask("vnd.farmmaps.task.bofek")
|
|
||||||
@Injectable()
|
|
||||||
@Component({
|
|
||||||
selector: 'fm-map-item-list-item-bofek',
|
|
||||||
templateUrl: './item-list-item-bofek.component.html',
|
|
||||||
styleUrls: ['./item-list-item-bofek.component.css']
|
|
||||||
})
|
|
||||||
export class ItemListItemBofekComponent extends AbstractItemListItemComponent implements OnInit {
|
|
||||||
@Input() item: IListItem;
|
|
||||||
feature;
|
|
||||||
|
|
||||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, private itemService$: ItemService) {
|
|
||||||
super(store, itemTypeService);
|
|
||||||
}
|
|
||||||
ngOnInit() {
|
|
||||||
this.itemService$.getItem(this.item.code).subscribe(i => {
|
|
||||||
this.itemService$.getChildItemList(i.parentCode, "vnd.farmmaps.itemtype.trijntje").subscribe(t => {
|
|
||||||
if (t.length > 0) {
|
|
||||||
var data = t[0].data;
|
|
||||||
var bofekId = data["wwl-yieldloss-data"]["feature-with-largest-area"];
|
|
||||||
var features = data["wwl-yieldloss-data"]["features"];
|
|
||||||
for (var i = 0; i < features.length; i++) {
|
|
||||||
if (features[i]["bodem"] == bofekId) {
|
|
||||||
this.feature = features[i];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})
|
|
||||||
})
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
.head {
|
|
||||||
color: grey;
|
|
||||||
font-weight: bold;
|
|
||||||
/*border-bottom:1px solid black;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.body {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mean {
|
|
||||||
text-align: center;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 2rem;
|
|
||||||
line-height: 7.5rem;
|
|
||||||
color: deeppink;
|
|
||||||
/*border-right:1px solid black;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.min {
|
|
||||||
/*border-bottom:1px solid black;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.min, .max {
|
|
||||||
vertical-align: middle;
|
|
||||||
line-height: 3.48rem;
|
|
||||||
color: gray;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.unit {
|
|
||||||
font-size: 0.6rem;
|
|
||||||
color: gray;
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
<div *ngIf="(selectedItem|async) as selectedItem; else noData">
|
|
||||||
|
|
||||||
<div *ngIf="selectedItem.data.layers[0].renderer.band.histogram;let histogram">
|
|
||||||
<div class="widget">
|
|
||||||
<div class="d-flex flex-column justify-content-center w-100 h-100">
|
|
||||||
<div class="head h-20 p-1">Height</div>
|
|
||||||
<div class="body d-flex flex-row h-100 w-100">
|
|
||||||
<div *ngIf="histogram.mean; else noMeanPresent">
|
|
||||||
<div class="mean flex-grow-1 pr-2 pl-2">{{histogram.mean | number:'0.1-2'}}<span class="unit"></span></div>
|
|
||||||
</div>
|
|
||||||
<ng-template #noMeanPresent>
|
|
||||||
<div class="mean flex-grow-1 pr-2 pl-2">{{(histogram.max+histogram.min)/2 | number:'0.1-2'}}<span class="unit">‰</span></div>
|
|
||||||
</ng-template>
|
|
||||||
<div class="d-flex flex-column w-20">
|
|
||||||
<div class="justify-content-center pr-2 pl-2 min">{{histogram.min | number:'0.1-2'}}</div>
|
|
||||||
<div class="justify-content-center pr-2 pl-2 max">{{histogram.max | number:'0.1-2'}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ng-template #noData>
|
|
||||||
<div class="widget">
|
|
||||||
<div class="d-flex flex-column justify-content-center w-100 h-100">
|
|
||||||
<div class="head h-20 p-1">Height</div>
|
|
||||||
<div class="body d-flex flex-row h-100 w-100">
|
|
||||||
<div class="p-1">No data available</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
@ -1,32 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { Input, Injectable } from '@angular/core';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import * as mapReducers from '../../reducers/map.reducer';
|
|
||||||
import { commonReducers, ItemTypeService, IItem, Item, ItemService, FolderService, IListItem } from '@farmmaps/common';
|
|
||||||
import { ForItemType } from '../for-item/for-itemtype.decorator';
|
|
||||||
import { ForSourceTask } from '../for-item/for-sourcetask.decorator';
|
|
||||||
import { AbstractItemListItemComponent } from '../item-list-item/item-list-item.component'
|
|
||||||
import { withLatestFrom, switchMap, map, switchMapTo, catchError, mergeMap, delay } from 'rxjs/operators';
|
|
||||||
import { Observable, of } from 'rxjs';
|
|
||||||
import { ControlScaleLineComponent } from 'ngx-openlayers';
|
|
||||||
|
|
||||||
|
|
||||||
@ForItemType("vnd.farmmaps.itemtype.geotiff.processed")
|
|
||||||
@ForSourceTask("vnd.farmmaps.task.ahn")
|
|
||||||
@Injectable()
|
|
||||||
@Component({
|
|
||||||
selector: 'fm-map-item-list-item-height',
|
|
||||||
templateUrl: './item-list-item-height.component.html',
|
|
||||||
styleUrls: ['./item-list-item-height.component.css']
|
|
||||||
})
|
|
||||||
export class ItemListItemHeightComponent extends AbstractItemListItemComponent implements OnInit {
|
|
||||||
@Input() item: IListItem;
|
|
||||||
selectedItem: Observable<IItem>;
|
|
||||||
|
|
||||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, private itemService$: ItemService) {
|
|
||||||
super(store, itemTypeService);
|
|
||||||
}
|
|
||||||
ngOnInit() {
|
|
||||||
this.selectedItem = this.itemService$.getItem(this.item.code);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
<div *ngIf="(selectedItem|async) as selectedItem">
|
|
||||||
<div class="widget d-flex flex-column p-1">
|
|
||||||
<div class="head" i18n>
|
|
||||||
Shadow index
|
|
||||||
</div>
|
|
||||||
<div class="d-flex flex-column">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" [attr.fill]="sunColor" width="100" height="100">
|
|
||||||
<path
|
|
||||||
d="m234.3 139.4c-66.7 0-120.9 54.2-120.9 120.9 0 66.7 54.2 120.9 120.9 120.9 66.7 0 120.9-54.2 120.9-120.9 0-66.7-54.2-120.9-120.9-120.9z"
|
|
||||||
class="a"/>
|
|
||||||
<path
|
|
||||||
d="m234.3 118.7c7.4 0 13.4-6 13.4-13.4V63.3c0-7.4-6-13.4-13.4-13.4-7.4 0-13.4 6-13.4 13.4v41.9c0 7.4 6 13.4 13.4 13.4z"
|
|
||||||
class="a"/>
|
|
||||||
<path
|
|
||||||
d="m234.3 402c-7.4 0-13.4 6-13.4 13.4v41.9c0 7.4 6 13.4 13.4 13.4 7.4 0 13.4-6 13.4-13.4v-41.9c0-7.4-6-13.4-13.4-13.4z"
|
|
||||||
class="a"/>
|
|
||||||
<path
|
|
||||||
d="m115.2 160.2c5.2 5.2 13.8 5.2 19 0 5.2-5.2 5.2-13.8 0-19l-29.7-29.7c-5.2-5.2-13.8-5.2-19 0-5.2 5.2-5.2 13.8 0 19z"
|
|
||||||
class="a"/>
|
|
||||||
<path
|
|
||||||
d="m353.4 360.5c-5.2-5.2-13.8-5.2-19 0-5.2 5.2-5.2 13.8 0 19l29.7 29.7c5.2 5.2 13.8 5.2 19 0 5.2-5.2 5.2-13.8 0-19z"
|
|
||||||
class="a"/>
|
|
||||||
<path
|
|
||||||
d="m92.7 260.3c0-7.4-6-13.4-13.4-13.4H37.3c-7.4 0-13.4 6-13.4 13.4 0 7.4 6 13.4 13.4 13.4h41.9c7.4 0 13.4-6 13.4-13.4z"
|
|
||||||
class="a"/>
|
|
||||||
<path
|
|
||||||
d="m431.3 246.9h-41.9c-7.4 0-13.4 6-13.4 13.4 0 7.4 6 13.4 13.4 13.4h41.9c7.4 0 13.4-6 13.4-13.4 0-7.4-6-13.4-13.4-13.4z"
|
|
||||||
class="a"/>
|
|
||||||
<path
|
|
||||||
d="m115.2 360.5-29.7 29.7c-5.2 5.2-5.2 13.8 0 19 5.2 5.2 13.8 5.2 19 0l29.7-29.7c5.2-5.2 5.2-13.8 0-19-5.2-5.2-13.8-5.2-19 0z"
|
|
||||||
class="a"/>
|
|
||||||
<path
|
|
||||||
d="m353.4 160.2 29.7-29.7c5.2-5.2 5.2-13.8 0-19-5.2-5.2-13.8-5.2-19 0l-29.7 29.7c-5.2 5.2-5.2 13.8 0 19 5.2 5.2 13.8 5.2 19 0z"
|
|
||||||
class="a"/>
|
|
||||||
<path [attr.d]="getSunShadowPath()" class="a" [attr.fill]="'black'"/>
|
|
||||||
</svg>
|
|
||||||
<div class="mean align-self-end">{{getMeanShadowValue(selectedItem) | number:'0.2-2'}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,17 +0,0 @@
|
|||||||
.head {
|
|
||||||
color: grey;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mean {
|
|
||||||
text-align: center;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.9rem;
|
|
||||||
color: deeppink;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
import {Observable} from 'rxjs';
|
|
||||||
import {Component, Injectable, Input, OnInit} from '@angular/core';
|
|
||||||
import {Store} from '@ngrx/store';
|
|
||||||
import * as mapReducers from '../../reducers/map.reducer';
|
|
||||||
import {commonReducers, IItem, IListItem, ItemService, ItemTypeService} from '@farmmaps/common';
|
|
||||||
import {ForItemType} from '../for-item/for-itemtype.decorator';
|
|
||||||
import {ForSourceTask} from '../for-item/for-sourcetask.decorator';
|
|
||||||
import {AbstractItemListItemComponent} from '../item-list-item/item-list-item.component'
|
|
||||||
import {map} from "rxjs/operators";
|
|
||||||
|
|
||||||
@ForItemType("vnd.farmmaps.itemtype.geotiff.processed")
|
|
||||||
@ForSourceTask("vnd.farmmaps.task.shadow")
|
|
||||||
@Injectable()
|
|
||||||
@Component({
|
|
||||||
selector: 'fm-map-item-list-item-shadow',
|
|
||||||
templateUrl: './item-list-item-shadow.component.html',
|
|
||||||
styleUrls: ['./item-list-item-shadow.component.scss']
|
|
||||||
})
|
|
||||||
export class ItemListItemShadowComponent extends AbstractItemListItemComponent implements OnInit {
|
|
||||||
@Input() item: IListItem;
|
|
||||||
selectedItem: Observable<IItem>;
|
|
||||||
|
|
||||||
public sunCenter = {x: 235.9, y: 259.4};
|
|
||||||
public sunStart = {x: 0, y: 0};
|
|
||||||
public sunEndRelative = {x: 0, y: 0};
|
|
||||||
public largeArc = 0;
|
|
||||||
public radius = 120;
|
|
||||||
|
|
||||||
public sunColor = '#ffcc00';
|
|
||||||
|
|
||||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService,
|
|
||||||
private itemService$: ItemService) {
|
|
||||||
super(store, itemTypeService);
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.selectedItem = this.itemService$.getItem(this.item.code)
|
|
||||||
.pipe(map(item => {
|
|
||||||
const shadowIndex = this.getMeanShadowValue(item);
|
|
||||||
this.calculateSunValues(shadowIndex);
|
|
||||||
return item;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateSunValues(shadowIndex) {
|
|
||||||
const dotProduct = shadowIndex * 2 - 1;
|
|
||||||
this.largeArc = dotProduct > 0 ? 1 : 0;
|
|
||||||
|
|
||||||
const angle = Math.acos(dotProduct);
|
|
||||||
const yRadius = this.radius * Math.sin(-angle);
|
|
||||||
|
|
||||||
this.sunStart.x = this.sunCenter.x + this.radius * dotProduct;
|
|
||||||
this.sunStart.y = this.sunCenter.y + yRadius;
|
|
||||||
this.sunEndRelative.x = this.sunStart.x;
|
|
||||||
this.sunEndRelative.y = this.sunCenter.y - yRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
getSunShadowPath() {
|
|
||||||
return `M${this.sunStart.x} ${this.sunStart.y} A${this.radius},${this.radius} 0 ${this.largeArc},0 ${this.sunEndRelative.x} ${this.sunEndRelative.y}z`;
|
|
||||||
}
|
|
||||||
|
|
||||||
getMeanShadowValue(item): number {
|
|
||||||
return item.data.layers[0].renderer.band.histogram.mean;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
.head {
|
|
||||||
color: grey;
|
|
||||||
font-weight:bold;
|
|
||||||
/*border-bottom:1px solid black;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.body {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mean {
|
|
||||||
text-align: center;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size:2rem;
|
|
||||||
line-height: 7.5rem;
|
|
||||||
color:deeppink;
|
|
||||||
/*border-right:1px solid black;*/
|
|
||||||
}
|
|
||||||
.min {
|
|
||||||
/*border-bottom:1px solid black;*/
|
|
||||||
}
|
|
||||||
.min, .max {
|
|
||||||
vertical-align: middle;
|
|
||||||
line-height: 3.48rem;
|
|
||||||
color:gray;
|
|
||||||
font-size:1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.unit {
|
|
||||||
font-size:0.8rem;
|
|
||||||
color:gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dateformat {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
<div *ngIf="(lastTemporalItem$|async) as lastChildItem">
|
|
||||||
<div *ngIf="lastChildItem.data.layers[0].renderer.band.histogram;let histogram">
|
|
||||||
<div class="widget" (click)="onWidgetClicked()">
|
|
||||||
<div class="d-flex flex-column justify-content-center w-100 h-100">
|
|
||||||
<div class="head h-20 p-1">Soil moisture (<span class="unit">%</span>)</div>
|
|
||||||
<div class="dateformat p-1">{{lastChildItem.dataDate | date : 'shortDate'}}</div>
|
|
||||||
<div class="body d-flex flex-row h-100 w-100">
|
|
||||||
<div *ngIf="histogram.mean; else noMeanPresent">
|
|
||||||
<div class="mean flex-grow-1 pr-2 pl-2">{{histogram.mean/10 | number:'0.1-2'}}</div>
|
|
||||||
</div>
|
|
||||||
<ng-template #noMeanPresent>
|
|
||||||
<div class="mean flex-grow-1 pr-2 pl-2">{{(histogram.max+histogram.min)/2 | number:'0.1-2'}}</div>
|
|
||||||
</ng-template>
|
|
||||||
<div class="d-flex flex-column w-20">
|
|
||||||
<div class="justify-content-center pr-2 pl-2 min">{{histogram.min/10 | number:'0.1-2'}}</div>
|
|
||||||
<div class="justify-content-center pr-2 pl-2 max">{{histogram.max/10 | number:'0.1-2'}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,42 +0,0 @@
|
|||||||
import {Component, Injectable, Input, OnInit} from '@angular/core';
|
|
||||||
import {Store} from '@ngrx/store';
|
|
||||||
import * as mapReducers from '../../reducers/map.reducer';
|
|
||||||
import { commonReducers, ItemTypeService, IItem, ItemService, IListItem } from '@farmmaps/common';
|
|
||||||
import { ForItemType } from '../for-item/for-itemtype.decorator';
|
|
||||||
import { ForSourceTask } from '../for-item/for-sourcetask.decorator';
|
|
||||||
import { AbstractItemListItemComponent } from '../item-list-item/item-list-item.component'
|
|
||||||
import { map, mergeMap } from 'rxjs/operators';
|
|
||||||
import { Observable, of } from 'rxjs';
|
|
||||||
import {Router} from "@angular/router";
|
|
||||||
|
|
||||||
|
|
||||||
@ForItemType("vnd.farmmaps.itemtype.temporal")
|
|
||||||
@ForSourceTask("vnd.farmmaps.task.vandersat")
|
|
||||||
@Injectable()
|
|
||||||
@Component({
|
|
||||||
selector: 'fm-map-item-list-item-temporal',
|
|
||||||
templateUrl: './item-list-item-temporal.component.html',
|
|
||||||
styleUrls: ['./item-list-item-temporal.component.css']
|
|
||||||
})
|
|
||||||
export class ItemListItemTemporalComponent extends AbstractItemListItemComponent implements OnInit {
|
|
||||||
@Input() item: IListItem;
|
|
||||||
lastTemporalItem$: Observable<IItem>;
|
|
||||||
|
|
||||||
constructor(store: Store<mapReducers.State | commonReducers.State>,
|
|
||||||
itemTypeService: ItemTypeService, private itemService: ItemService,
|
|
||||||
private router: Router) {
|
|
||||||
super(store, itemTypeService);
|
|
||||||
}
|
|
||||||
ngOnInit() {
|
|
||||||
this.lastTemporalItem$ = this.itemService
|
|
||||||
.getChildItemList(this.item.code, "vnd.farmmaps.itemtype.geotiff.processed")
|
|
||||||
.pipe(
|
|
||||||
map(list => list.length>0? list.sort().slice(-1)[0]:null),
|
|
||||||
mergeMap(li => li==null?of(null):this.itemService.getItem(li.code)));
|
|
||||||
}
|
|
||||||
|
|
||||||
onWidgetClicked() {
|
|
||||||
event.stopPropagation();
|
|
||||||
this.router.navigate(['viewer/vandersat/item', this.item.code]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
<div *ngIf="(item$|async) as item" class="widget d-flex flex-column p-1" (click)="onWidgetClicked($event)">
|
|
||||||
<ng-container *ngIf="getLastDailyOutput(item) as dailyOutput">
|
|
||||||
<div class="head" i18n>Yield forecast</div>
|
|
||||||
<div class="d-flex flex-row justify-content-between">
|
|
||||||
<div>(<span class="unit">ton/ha</span>)</div>
|
|
||||||
<div class="dateformat">{{dailyOutput.date | date : 'd/M/yy'}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex flex-column">
|
|
||||||
<div class="fm fa-5x fm-potato"></div>
|
|
||||||
<div class="value align-self-end">{{dailyOutput.tuberwt[1] | number:'0.1-1'}}</div>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
|
@ -1,36 +0,0 @@
|
|||||||
.head {
|
|
||||||
color: grey;
|
|
||||||
font-weight: bold;
|
|
||||||
/*border-bottom:1px solid black;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.body {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value {
|
|
||||||
text-align: center;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.9rem;
|
|
||||||
color: deeppink;
|
|
||||||
/*border-right:1px solid black;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.unit {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dateformat {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fm-potato {
|
|
||||||
color: saddlebrown;
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
import {Component, Injectable, Input, OnInit} from '@angular/core';
|
|
||||||
import {Store} from '@ngrx/store';
|
|
||||||
import * as mapReducers from '../../reducers/map.reducer';
|
|
||||||
import {commonReducers, IItem, IListItem, ItemService, ItemTypeService} from '@farmmaps/common';
|
|
||||||
import {ForItemType} from '../for-item/for-itemtype.decorator';
|
|
||||||
import {ForSourceTask} from '../for-item/for-sourcetask.decorator';
|
|
||||||
import {AbstractItemListItemComponent} from '../item-list-item/item-list-item.component'
|
|
||||||
import {Observable} from "rxjs";
|
|
||||||
import {Router} from "@angular/router";
|
|
||||||
|
|
||||||
@ForItemType("vnd.farmmaps.itemtype.tipstar")
|
|
||||||
@ForSourceTask("vnd.farmmaps.task.tipstar")
|
|
||||||
@Injectable()
|
|
||||||
@Component({
|
|
||||||
selector: 'fm-map-item-list-item-tipstar',
|
|
||||||
templateUrl: './item-list-item-tipstar.component.html',
|
|
||||||
styleUrls: ['./item-list-item-tipstar.component.scss']
|
|
||||||
})
|
|
||||||
export class ItemListItemTipstarComponent extends AbstractItemListItemComponent implements OnInit {
|
|
||||||
@Input() item: IListItem;
|
|
||||||
|
|
||||||
item$: Observable<IItem>;
|
|
||||||
|
|
||||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService,
|
|
||||||
private itemService$: ItemService, private router: Router) {
|
|
||||||
super(store, itemTypeService);
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.item$ = this.itemService$.getItem(this.item.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
onWidgetClicked(event: MouseEvent) {
|
|
||||||
event.stopPropagation();
|
|
||||||
this.router.navigate(['viewer/tipstar/item', this.item.code]);
|
|
||||||
}
|
|
||||||
|
|
||||||
getLastDailyOutput(item) {
|
|
||||||
if (item == null || item.data == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const itemData = item.data;
|
|
||||||
if (itemData.dailyOutput == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return itemData.dailyOutput[itemData.dailyOutput.length - 1]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
.head {
|
|
||||||
color: grey;
|
|
||||||
font-weight: bold;
|
|
||||||
/*border-bottom:1px solid black;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.body {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tpvocmet {
|
|
||||||
text-align: center;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.9rem;
|
|
||||||
line-height: 7.2rem;
|
|
||||||
color: deeppink;
|
|
||||||
/*border-right:1px solid black;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.widget {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.unit {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dateformat {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
<div class="widget">
|
|
||||||
<div class="d-flex flex-column justify-content-center w-100 h-100">
|
|
||||||
<div class="head h-20 p-1" i18n>WatBal (<span class="unit">kg/ha</span>)</div>
|
|
||||||
<div class="body d-flex flex-column h-100 w-100">
|
|
||||||
<small i18n>Date:{{TPVOCMET?.Datum | date : 'shortDate'}}</small>
|
|
||||||
<small i18n>Bedrijf/Perceel:{{TPVOCMET?.BedrijfID}}/{{TPVOCMET?.PerceelID}}</small>
|
|
||||||
<small i18n>GewichtZonder:{{TPVOCMET?.GewichtZonder | number:'0.1-2'}}</small>
|
|
||||||
<small i18n>GewichtGroDro:{{TPVOCMET?.GewichtGroDro | number:'0.1-2'}}</small>
|
|
||||||
<small i18n>GewichtGroNat:{{TPVOCMET?.GewichtGroNat | number:'0.1-2'}}</small>
|
|
||||||
</div>
|
|
||||||
<fm-map-widget-status [stage]="stage" [info]="'WatBal is expected in spring 2020.'" i18n></fm-map-widget-status>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,34 +0,0 @@
|
|||||||
import { Observable, of } from 'rxjs';
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { Input, Injectable } from '@angular/core';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import * as mapReducers from '../../reducers/map.reducer';
|
|
||||||
import { commonReducers, ItemTypeService, IItem, Item, ItemService, IListItem } from '@farmmaps/common';
|
|
||||||
import { ForItemType } from '../for-item/for-itemtype.decorator';
|
|
||||||
import { ForSourceTask } from '../for-item/for-sourcetask.decorator';
|
|
||||||
import { AbstractItemListItemComponent } from '../item-list-item/item-list-item.component'
|
|
||||||
import { Stage } from '../widget-status/widget-status.component';
|
|
||||||
|
|
||||||
@ForItemType("vnd.farmmaps.itemtype.watbal")
|
|
||||||
@ForSourceTask("vnd.farmmaps.task.watbal")
|
|
||||||
@Injectable()
|
|
||||||
@Component({
|
|
||||||
selector: 'fm-map-item-list-item-watbal',
|
|
||||||
templateUrl: './item-list-item-watbal.component.html',
|
|
||||||
styleUrls: ['./item-list-item-watbal.component.css']
|
|
||||||
})
|
|
||||||
export class ItemListItemWatBalComponent extends AbstractItemListItemComponent implements OnInit {
|
|
||||||
@Input() item: IListItem;
|
|
||||||
TPVOCMET;
|
|
||||||
stage = Stage.DevelopmentPreAlpha;
|
|
||||||
|
|
||||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, private itemService$: ItemService) {
|
|
||||||
super(store, itemTypeService);
|
|
||||||
}
|
|
||||||
ngOnInit() {
|
|
||||||
this.itemService$.getItem(this.item.code).subscribe(i => {
|
|
||||||
var data = i.data.HTAKKER_Input.TPVOCMET;
|
|
||||||
this.TPVOCMET = data[data.length - 1];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
<div *ngIf="(weather|async);let currentweather" style="padding: 10px;">
|
|
||||||
<div style="position:absolute">{{currentweather.temp}}°</div>
|
|
||||||
<img src="/images/weather/{{currentweather.icon_code}}.svg">
|
|
||||||
</div>
|
|
@ -1,27 +0,0 @@
|
|||||||
@import "../../_theme.scss";
|
|
||||||
@import "~bootstrap/scss/bootstrap.scss";
|
|
||||||
|
|
||||||
.widget {
|
|
||||||
padding:0.8rem;
|
|
||||||
height:100%;
|
|
||||||
width:100%;
|
|
||||||
color:#ffffff;
|
|
||||||
position:relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
display:block;
|
|
||||||
font-size:6rem;
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
.title {
|
|
||||||
display:block;
|
|
||||||
position:absolute;
|
|
||||||
width:calc(100% - 1.6rem );
|
|
||||||
padding-top:0.5rem;
|
|
||||||
bottom:0.8rem;
|
|
||||||
height:2rem;
|
|
||||||
overflow:hidden;
|
|
||||||
white-space:nowrap;
|
|
||||||
text-overflow:ellipsis;
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
import { Component, Input, Injectable } from '@angular/core';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import * as mapReducers from '../../reducers/map.reducer';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { mergeMap } from 'rxjs/operators';
|
|
||||||
import { commonReducers, ItemTypeService, ItemService } from '@farmmaps/common';
|
|
||||||
import { AbstractItemWidgetComponent} from '../item-list-item/item-list-item.component';
|
|
||||||
import { ForItemType } from '../for-item/for-itemtype.decorator';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
import { GeoJSON } from 'ol/format';
|
|
||||||
import { getCenter, Extent, createEmpty, extend } from 'ol/extent';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
@Component({
|
|
||||||
selector: 'fm-map-item-widget-weather',
|
|
||||||
templateUrl: './item-widget-weather.component.html',
|
|
||||||
styleUrls: ['./item-widget-weather.component.scss']
|
|
||||||
})
|
|
||||||
export class ItemWidgetWeatherComponent extends AbstractItemWidgetComponent {
|
|
||||||
|
|
||||||
private _format: GeoJSON;
|
|
||||||
|
|
||||||
constructor(store: Store<mapReducers.State | commonReducers.State>, itemTypeService: ItemTypeService, public http: HttpClient, private itemService$: ItemService) {
|
|
||||||
super(store, itemTypeService);
|
|
||||||
this._format = new GeoJSON();
|
|
||||||
}
|
|
||||||
|
|
||||||
public weather: Observable<any>;
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.weather = this.itemService$.getItem(this.item.code).pipe(mergeMap(i => {
|
|
||||||
console.debug(i.geometry);
|
|
||||||
var geometry = this._format.readGeometry(i.geometry);
|
|
||||||
var centroid = getCenter(geometry.getExtent());
|
|
||||||
var url = 'https://weather.akkerweb.nl/v2/data/currentobservation/?c=' + centroid[0] + ',' + centroid[1] + '&key=5f17ef36283b49e9b099a1f4064fbf3d';
|
|
||||||
var cw = this.http.get(url);
|
|
||||||
return cw;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
@ -39,6 +39,7 @@ import { SessionClearedComponent } from './components/session-cleared/session-cl
|
|||||||
import { ResumableFileUploadService } from './components/resumable-file-upload/resumable-file-upload.service';
|
import { ResumableFileUploadService } from './components/resumable-file-upload/resumable-file-upload.service';
|
||||||
import { ResumableFileUploadComponent } from './components/resumable-file-upload/resumable-file-upload.component';
|
import { ResumableFileUploadComponent } from './components/resumable-file-upload/resumable-file-upload.component';
|
||||||
import { NotFoundComponent } from './components/not-found/not-found.component';
|
import { NotFoundComponent } from './components/not-found/not-found.component';
|
||||||
|
import { NotImplementedComponent } from './components/not-implemented/not-implemented.component';
|
||||||
import { SidePanelComponent } from './components/side-panel/side-panel.component';
|
import { SidePanelComponent } from './components/side-panel/side-panel.component';
|
||||||
import { TimespanComponent } from './components/timespan/timespan.component';
|
import { TimespanComponent } from './components/timespan/timespan.component';
|
||||||
import { TagInputComponent } from './components/tag-input/tag-input.component';
|
import { TagInputComponent } from './components/tag-input/tag-input.component';
|
||||||
@ -76,6 +77,7 @@ export {FolderService,
|
|||||||
ResumableFileUploadService,
|
ResumableFileUploadService,
|
||||||
ResumableFileUploadComponent,
|
ResumableFileUploadComponent,
|
||||||
NotFoundComponent,
|
NotFoundComponent,
|
||||||
|
NotImplementedComponent,
|
||||||
SidePanelComponent,
|
SidePanelComponent,
|
||||||
TimespanComponent,
|
TimespanComponent,
|
||||||
TagInputComponent,
|
TagInputComponent,
|
||||||
@ -115,6 +117,7 @@ export {FolderService,
|
|||||||
SidePanelComponent,
|
SidePanelComponent,
|
||||||
SafePipe,
|
SafePipe,
|
||||||
NotFoundComponent,
|
NotFoundComponent,
|
||||||
|
NotImplementedComponent,
|
||||||
ResumableFileUploadComponent,
|
ResumableFileUploadComponent,
|
||||||
TimespanComponent,
|
TimespanComponent,
|
||||||
TagInputComponent,
|
TagInputComponent,
|
||||||
@ -130,6 +133,7 @@ export {FolderService,
|
|||||||
SidePanelComponent,
|
SidePanelComponent,
|
||||||
SafePipe,
|
SafePipe,
|
||||||
NotFoundComponent,
|
NotFoundComponent,
|
||||||
|
NotImplementedComponent,
|
||||||
ResumableFileUploadComponent,
|
ResumableFileUploadComponent,
|
||||||
TimespanComponent,
|
TimespanComponent,
|
||||||
TagInputComponent,
|
TagInputComponent,
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
<div class="wrapper">
|
||||||
|
<header class="header header--large">
|
||||||
|
<h1 class="title">Function is not implemented in this code</h1>
|
||||||
|
</header>
|
||||||
|
</div>
|
@ -0,0 +1,11 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'fm-not-implemented',
|
||||||
|
templateUrl: './not-implemented.component.html'
|
||||||
|
})
|
||||||
|
export class NotImplementedComponent implements OnInit {
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() { }
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user