import {Injectable} from '@angular/core'; import {HttpClient} from '@angular/common/http'; import {AppConfig} from '../shared/app.config'; import {Observable} from 'rxjs'; import {WeatherCurrentObservation} from '../models/weatherCurrentObservation'; import {DatePipe} from '@angular/common'; import {IItem} from '@farmmaps/common'; import {WeatherData} from '../models/WeatherData'; import {GeoJSON} from 'ol/format'; import {map, switchMap} from 'rxjs/operators'; import {getCenter} from 'ol/extent'; @Injectable({ providedIn: 'root', }) export class WeatherService { private apiCurrentObservationUrl = 'currentobservation'; private apiObservation = 'observation'; private apiForecast = 'forecast'; private format: GeoJSON; constructor(public httpClient: HttpClient, public appConfig: AppConfig, private datePipe: DatePipe) { this.format = new GeoJSON(); } public GetCurrentObservation(centroid: number[]): Observable { const endpoint = this.appConfig.getConfig('weatherApiEndPoint'); const apiKey = this.appConfig.getConfig('weatherApiKey'); const observationUrl = `${endpoint}${this.apiCurrentObservationUrl}/?c=${centroid[0]},${centroid[1]}&key=${apiKey}`; return this.httpClient.get(observationUrl); } public getWeatherRangeForItem(item: IItem, daysBefore = 10, daysAfter = 10): Observable { const geometry = this.format.readGeometry(item.geometry); const centroid = getCenter(geometry.getExtent()); const currentDate = new Date(Date.now()); const sd = new Date(Date.now()); const ed = new Date(Date.now()); sd.setDate((currentDate.getDate() - daysBefore)); ed.setDate((currentDate.getDate() + daysAfter)); return this.getWeatherRange(centroid, this.datePipe.transform(sd, 'yyyy-MM-ddThh:mm:ss'), this.datePipe.transform(ed, 'yyyy-MM-ddThh:mm:ss')); } public getWeatherRange(centroid: number[], startDate: string, endDate: string): Observable { const endpoint = this.appConfig.getConfig('weatherApiEndPoint'); const apiKey = this.appConfig.getConfig('weatherApiKey'); // weather does not support UTC format, also remove Z const sd = encodeURIComponent(this.removeUTCZ(startDate)); const ed = encodeURIComponent(this.removeUTCZ(endDate)); const historical = `${endpoint}${this.apiObservation}/?c=${centroid[0]},${centroid[1]}&sd=${sd}&ed=${ed}&interval=daily&key=${apiKey}`; const forecast = `${endpoint}${this.apiForecast}/?c=${centroid[0]},${centroid[1]}&interval=daily&key=${apiKey}`; return this.httpClient.get(historical).pipe( map(h => h.map(this.createWeatherDataFromHistorical)), switchMap(h => { return this.httpClient.get(forecast) .pipe( map(f => [...h, ...f.filter(fd => fd.date <= endDate) .map(this.createWeatherDataFromForecast)])); }) ); } private createWeatherDataFromHistorical(hd): WeatherData { return {time: hd.date, minTemp: hd.minimumTemperature, maxTemp: hd.maximumTemperature, relativeHumidity: hd.relativeHumidity, rain: hd.precipitation}; } private createWeatherDataFromForecast(fd): WeatherData { return {time: fd.date, minTemp: fd.minimumTemperature, maxTemp: fd.maximumTemperature, relativeHumidity: fd.relativeHumidity, rain: fd.rain}; } private removeUTCZ(dateFormat: string): string { if (dateFormat[dateFormat.length - 1] === 'Z') { return dateFormat.substring(0, dateFormat.length - 1); } return dateFormat; } }