-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1475 from rodekruis/feat.river-gauges-test
Feat.river gauges test
- Loading branch information
Showing
102 changed files
with
1,647 additions
and
1,068 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
...d/src/app/components/leaflet-popup/dynamic-point-popup/dynamic-point-popup.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<div | ||
class="leaflet--dynamic-point-popup--header" | ||
[ngClass]="layerName" | ||
[style]="glofasHeaderStyle" | ||
> | ||
<strong>{{ title }}</strong> | ||
</div> | ||
<div class="leaflet--dynamic-point-popup--content"> | ||
<ng-container [ngSwitch]="layerName"> | ||
<app-river-gauge-popup-content | ||
*ngSwitchCase="ibfLayerName.gauges" | ||
[data]="riverGauge" | ||
></app-river-gauge-popup-content> | ||
<app-typhoon-trackpoint-popup-content | ||
*ngSwitchCase="ibfLayerName.typhoonTrack" | ||
[data]="typhoonData" | ||
></app-typhoon-trackpoint-popup-content> | ||
<app-glofas-station-popup-content | ||
*ngSwitchCase="ibfLayerName.glofasStations" | ||
[data]="glofasData" | ||
></app-glofas-station-popup-content> | ||
</ng-container> | ||
</div> | ||
<div class="leaflet--dynamic-point-popup--footer" [style]="glofasFooterStyle"> | ||
<div> | ||
<strong>{{ footerContent }}</strong> | ||
</div> | ||
</div> |
37 changes: 37 additions & 0 deletions
37
...d/src/app/components/leaflet-popup/dynamic-point-popup/dynamic-point-popup.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
.leaflet--dynamic-point-popup--header { | ||
&.gauges { | ||
background: var(--ion-color-ibf-no-alert-primary); | ||
} | ||
&.typhoon_track { | ||
background: var(--ion-color-ibf-primary); | ||
} | ||
|
||
color: white; | ||
padding: 8px; | ||
border-radius: 8px 8px 0 0; | ||
} | ||
|
||
.leaflet--dynamic-point-popup--content { | ||
padding: 8px; | ||
} | ||
|
||
.leaflet--dynamic-point-popup--footer { | ||
&.gauges { | ||
color: var(--ion-color-ibf-no-alert-primary); | ||
} | ||
&.typhoon_track { | ||
color: var(--ion-color-ibf-primary); | ||
} | ||
&.glofas_stations { | ||
color: red; | ||
} | ||
|
||
padding: 0 8px; | ||
border-radius: 0 0 8px 8px; | ||
|
||
div { | ||
padding: 8px 0; | ||
text-align: center; | ||
border-top: 1px solid var(--ion-color-ibf-grey-light); | ||
} | ||
} |
144 changes: 144 additions & 0 deletions
144
...ard/src/app/components/leaflet-popup/dynamic-point-popup/dynamic-point-popup.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import { Component, Input, OnInit } from '@angular/core'; | ||
import { TranslateService } from '@ngx-translate/core'; | ||
import { LatLng } from 'leaflet'; | ||
import { EapAlertClass, EapAlertClasses } from '../../../models/country.model'; | ||
import { RiverGauge, Station } from '../../../models/poi.model'; | ||
import { IbfLayerName } from '../../../types/ibf-layer'; | ||
import { LeadTime } from '../../../types/lead-time'; | ||
|
||
@Component({ | ||
selector: 'app-dynamic-point-popup', | ||
templateUrl: './dynamic-point-popup.component.html', | ||
styleUrls: ['./dynamic-point-popup.component.scss'], | ||
}) | ||
export class DynamicPointPopupComponent implements OnInit { | ||
@Input() | ||
public layerName: IbfLayerName; | ||
|
||
@Input() | ||
public riverGauge?: RiverGauge; | ||
|
||
@Input() | ||
public typhoonTrackPoint?: { | ||
timestamp: string; | ||
category: string; | ||
markerLatLng: LatLng; | ||
passed: boolean; | ||
}; | ||
|
||
@Input() | ||
public glofasData?: { | ||
station: Station; | ||
leadTime: LeadTime; | ||
eapAlertClasses: EapAlertClasses; | ||
}; | ||
|
||
public typhoonData: { | ||
timestamp: string; | ||
category: string; | ||
}; | ||
|
||
public ibfLayerName = IbfLayerName; | ||
|
||
public title: string; | ||
public footerContent: string; | ||
|
||
public glofasHeaderStyle: string; | ||
public glofasFooterStyle: string; | ||
|
||
public eapAlertClass: EapAlertClass; | ||
|
||
private allowedLayers = [ | ||
IbfLayerName.gauges, | ||
IbfLayerName.typhoonTrack, | ||
IbfLayerName.glofasStations, | ||
]; | ||
|
||
constructor(private translate: TranslateService) {} | ||
|
||
ngOnInit(): void { | ||
if (!this.layerName || !this.allowedLayers.includes(this.layerName)) { | ||
return; | ||
} | ||
|
||
if (!this.riverGauge && !this.typhoonTrackPoint && !this.glofasData) { | ||
return; | ||
} | ||
|
||
if (this.layerName === IbfLayerName.typhoonTrack) { | ||
this.typhoonData = { | ||
timestamp: this.typhoonTrackPoint.timestamp, | ||
category: this.typhoonTrackPoint.category, | ||
}; | ||
} | ||
|
||
if ( | ||
this.layerName === IbfLayerName.glofasStations && | ||
this.glofasData.eapAlertClasses | ||
) { | ||
this.eapAlertClass = this.glofasData.eapAlertClasses[ | ||
this.glofasData.station.dynamicData.eapAlertClass | ||
]; | ||
} | ||
|
||
this.title = this.getTitle(); | ||
this.footerContent = this.getFooterContent(); | ||
|
||
this.glofasHeaderStyle = | ||
this.layerName === IbfLayerName.glofasStations | ||
? `background: var(--ion-color-${this.eapAlertClass.color});color: var(--ion-color-${this.eapAlertClass.color}-contrast);` | ||
: ''; | ||
|
||
this.glofasFooterStyle = | ||
this.layerName === IbfLayerName.glofasStations | ||
? `color: var(--ion-color-${this.eapAlertClass.color}${ | ||
this.eapAlertClass.color === 'ibf-yellow' ? '-contrast' : '' | ||
});` | ||
: ''; | ||
} | ||
|
||
private getTitle(): string { | ||
if (this.layerName === IbfLayerName.gauges) { | ||
return `${this.translate.instant('map-popups.river-gauge.header')} ${ | ||
this.riverGauge.fid | ||
} ${this.riverGauge.name}`; | ||
} | ||
|
||
if (this.layerName === IbfLayerName.typhoonTrack) { | ||
return `Typhoon track${this.typhoonTrackPoint.passed ? ' (passed)' : ''}`; | ||
} | ||
|
||
if (this.layerName === IbfLayerName.glofasStations) { | ||
return `${this.glofasData.station.stationCode} STATION: ${this.glofasData.station.stationName}`; | ||
} | ||
|
||
return ''; | ||
} | ||
|
||
private getFooterContent(): string { | ||
if (this.layerName === IbfLayerName.gauges) { | ||
return !this.riverGauge.dynamicData?.['water-level'] | ||
? '' | ||
: this.riverGauge.dynamicData?.['water-level'] <= | ||
this.riverGauge.dynamicData?.['water-level-reference'] | ||
? this.translate.instant('map-popups.river-gauge.below') | ||
: this.translate.instant('map-popups.river-gauge.above'); | ||
} | ||
|
||
if (this.layerName === IbfLayerName.typhoonTrack) { | ||
const lat = `${Math.abs(this.typhoonTrackPoint.markerLatLng.lat).toFixed( | ||
4, | ||
)}° ${this.typhoonTrackPoint.markerLatLng.lat > 0 ? 'N' : 'S'}`; | ||
const lng = `${Math.abs(this.typhoonTrackPoint.markerLatLng.lng).toFixed( | ||
4, | ||
)}° ${this.typhoonTrackPoint.markerLatLng.lng > 0 ? 'E' : 'W'}`; | ||
return `${lat}, ${lng}`; | ||
} | ||
|
||
if (this.layerName === IbfLayerName.glofasStations) { | ||
return this.eapAlertClass.label; | ||
} | ||
|
||
return ''; | ||
} | ||
} |
Empty file.
27 changes: 27 additions & 0 deletions
27
...ts/leaflet-popup/glofas-station-popup-content/glofas-station-popup-content.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<div style="margin-bottom: 4px"> | ||
{{ data?.leadTime }} forecast of | ||
<span | ||
title="The amount of water moving down a river at a given time and place" | ||
style=" | ||
text-decoration: underline; | ||
text-decoration-style: dotted; | ||
cursor: default; | ||
" | ||
>river discharge</span | ||
> | ||
in m<sup>3</sup>/s | ||
<ng-container *ngIf="data?.station?.forecastReturnPeriod"> | ||
<br /> | ||
(Corresponding to a return period of | ||
<strong>{{ data?.station?.forecastReturnPeriod }}</strong> years) | ||
</ng-container> | ||
</div> | ||
<app-threshold-bar | ||
[backgroundColor]="barBackgroundColor" | ||
[textColor]="barTextColor" | ||
[barWidth]="triggerWidth" | ||
[barValue]="addComma(barValue)" | ||
thresholdDescription="Trigger activation threshold" | ||
[thresholdValue]="data?.station?.dynamicData?.triggerLevel" | ||
[thresholdPosition]="80" | ||
></app-threshold-bar> |
65 changes: 65 additions & 0 deletions
65
...ents/leaflet-popup/glofas-station-popup-content/glofas-station-popup-content.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { Component, Input, OnInit } from '@angular/core'; | ||
import { EapAlertClass, EapAlertClasses } from '../../../models/country.model'; | ||
import { Station } from '../../../models/poi.model'; | ||
import { LeadTime } from '../../../types/lead-time'; | ||
|
||
@Component({ | ||
selector: 'app-glofas-station-popup-content', | ||
templateUrl: './glofas-station-popup-content.component.html', | ||
styleUrls: ['./glofas-station-popup-content.component.css'], | ||
}) | ||
export class GlofasStationPopupContentComponent implements OnInit { | ||
@Input() | ||
public data: { | ||
station: Station; | ||
leadTime: LeadTime; | ||
eapAlertClasses: EapAlertClasses; | ||
}; | ||
|
||
public barValue: number; | ||
public triggerWidth: number; | ||
public barBackgroundColor: string; | ||
public barTextColor: string; | ||
private eapAlertClass: EapAlertClass; | ||
|
||
ngOnInit(): void { | ||
if (!this.data) { | ||
return; | ||
} | ||
|
||
const difference = | ||
Number(this.data.station.dynamicData.forecastLevel) - | ||
Number(this.data.station.dynamicData.triggerLevel); | ||
const closeMargin = 0.05; | ||
const tooClose = | ||
Math.abs(difference) / this.data.station.triggerLevel < closeMargin; | ||
|
||
this.barValue = | ||
difference === 0 || !tooClose | ||
? Number(this.data.station.dynamicData.forecastLevel) | ||
: Number(this.data.station.dynamicData.triggerLevel) + | ||
Math.sign(difference) * | ||
Number(this.data.station.dynamicData.triggerLevel) * | ||
closeMargin; | ||
|
||
this.triggerWidth = Math.max( | ||
Math.min( | ||
Math.round( | ||
(this.barValue / Number(this.data.station.dynamicData.triggerLevel)) * | ||
100, | ||
), | ||
115, | ||
), | ||
0, | ||
); | ||
|
||
this.eapAlertClass = this.data.eapAlertClasses[ | ||
this.data.station.dynamicData.eapAlertClass | ||
]; | ||
|
||
this.barBackgroundColor = `var(--ion-color-${this.eapAlertClass.color})`; | ||
this.barTextColor = `var(--ion-color-${this.eapAlertClass.color}-contrast)`; | ||
} | ||
|
||
public addComma = (n) => Math.round(n).toLocaleString('en-US'); | ||
} |
54 changes: 54 additions & 0 deletions
54
...mponents/leaflet-popup/river-gauge-popup-content/river-gauge-popup-content.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<ng-container *ngIf="current"> | ||
<div | ||
style="margin-bottom: 4px; display: flex; justify-content: space-between" | ||
> | ||
<div> | ||
<ion-label style="font-size: 18px; padding-right: 8px"> | ||
<strong>{{ currentString }}</strong> | ||
{{ 'map-popups.river-gauge.unit' | translate }} | ||
{{ 'map-popups.river-gauge.sea-level' | translate }} | ||
</ion-label> | ||
<ion-label | ||
style="margin-right: 4px" | ||
[color]="difference <= 0 ? 'success' : 'danger'" | ||
> | ||
<ion-icon | ||
[name]="difference <= 0 ? 'caret-down-outline' : 'caret-up-outline'" | ||
></ion-icon | ||
>{{ differenceAbsolute }} | ||
{{ 'map-popups.river-gauge.unit' | translate }}</ion-label | ||
> | ||
</div> | ||
<app-tooltip | ||
[value]="'map-popups.river-gauge.tooltip' | translate" | ||
color="ibf-no-alert-primary" | ||
></app-tooltip> | ||
</div> | ||
<div style="margin-bottom: 4px"> | ||
<ion-label | ||
><strong>{{ | ||
'map-popups.river-gauge.current' | translate | ||
}}</strong></ion-label | ||
> | ||
</div> | ||
<app-threshold-bar | ||
backgroundColor="var(--ion-color-ibf-no-alert-primary)" | ||
textColor="var(--ion-color-ibf-white)" | ||
[barWidth]="triggerWidth" | ||
[barValue]="current + ('map-popups.river-gauge.unit' | translate)" | ||
[thresholdDescription]="'map-popups.river-gauge.normal' | translate" | ||
[thresholdValue]="reference + ('map-popups.river-gauge.unit' | translate)" | ||
[thresholdPosition]="45" | ||
></app-threshold-bar> | ||
</ng-container> | ||
<ng-container *ngIf="!current"> | ||
<div | ||
style="margin-bottom: 4px; display: flex; justify-content: space-between" | ||
> | ||
<div> | ||
<ion-label style="font-size: 18px; padding-right: 8px"> | ||
{{ 'map-popups.river-gauge.no-data' | translate }} | ||
</ion-label> | ||
</div> | ||
</div> | ||
</ng-container> |
22 changes: 22 additions & 0 deletions
22
...mponents/leaflet-popup/river-gauge-popup-content/river-gauge-popup-content.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
.leaflet--dynamic-point-popup--header { | ||
background: var(--ion-color-ibf-no-alert-primary); | ||
color: white; | ||
padding: 8px; | ||
border-radius: 8px 8px 0 0; | ||
} | ||
|
||
.leaflet--dynamic-point-popup--content { | ||
padding: 8px; | ||
} | ||
|
||
.leaflet--dynamic-point-popup--footer { | ||
color: var(--ion-color-ibf-no-alert-primary); | ||
padding: 0 8px; | ||
border-radius: 0 0 8px 8px; | ||
|
||
div { | ||
padding: 8px 0; | ||
text-align: center; | ||
border-top: 1px solid var(--ion-color-ibf-grey-light); | ||
} | ||
} |
Oops, something went wrong.