diff --git a/projects/common/src/fm/models/WeatherData.ts b/projects/common/src/fm/models/WeatherData.ts index b450d4b..e2de3f9 100644 --- a/projects/common/src/fm/models/WeatherData.ts +++ b/projects/common/src/fm/models/WeatherData.ts @@ -1,10 +1,11 @@ export interface WeatherData { - time: Date; - minTemp: number; - maxTemp: number; - relativeHumidity: number; - rain: number; - wspd?: number; - wdir_cardinal?: string; - wdir?: number; + date: Date; + iconCode: number; + minTemperature: number; + maxTemperature: number; + relHumidity: number; + precipitation: number; + wSpeed: number; + wCardinal: string; + wDir: number; } diff --git a/projects/common/src/fm/services/weather.service.ts b/projects/common/src/fm/services/weather.service.ts index b3bafad..024d7d5 100644 --- a/projects/common/src/fm/services/weather.service.ts +++ b/projects/common/src/fm/services/weather.service.ts @@ -54,28 +54,65 @@ export class WeatherService { 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}`; + const historical = `${endpoint}${this.apiObservation}/?c=${centroid[0]},${centroid[1]}&sd=${sd}&ed=${ed}&t=observation&interval=hourly&key=${apiKey}`; + const forecast = `${endpoint}${this.apiForecast}/?c=${centroid[0]},${centroid[1]}&interval=hourly&key=${apiKey}`; return this.httpClient.get(historical).pipe( - map(h => h.map(this.createWeatherDataFromHistorical)), + map(h => h.map(d => ({...d, rain: d.rainPastHour}))), switchMap(h => { return this.httpClient.get(forecast) .pipe( - map(f => [...h, ...f.filter(fd => fd.date <= endDate) - .map(this.createWeatherDataFromForecast)])); + map(f => this.hourlyToDaily([...h, ...f.filter(fd => fd.time <= endDate)]) + )); }) ); } - private createWeatherDataFromHistorical(hd): WeatherData { - return {time: hd.date, minTemp: hd.minimumTemperature, - maxTemp: hd.maximumTemperature, relativeHumidity: hd.relativeHumidity, rain: hd.precipitation}; + private hourlyToDaily(hourlyWeatherData: any[]): WeatherData[] { + const days = this.groupBy(hourlyWeatherData, hi => hi.time.split('T')[0]); + return Object.entries(days) + .reduce ( (result, entry) => { + const wData = entry[1]; + + const sortData = wData.sort(d => new Date(d.time).getHours() - 12); + const closestToTwelveOClockData = sortData[0]; + if (closestToTwelveOClockData.length === 0) { + return result; + } + + const bestCardinal = closestToTwelveOClockData.windDirectionCardinal; + const bestWindDirection = closestToTwelveOClockData.windDirection; + const bestIconCode = closestToTwelveOClockData.iconCode; + return [ + ...result, + { + date: entry[0], + iconCode: bestIconCode, + minTemperature: Math.min(...wData.map(d => d.temperature)), + maxTemperature: Math.max(...wData.map(d => d.temperature)), + relHumidity: wData.reduce( (r, e) => r + e.relativeHumidity, 0) / wData.length, + precipitation: wData.reduce( (r, e) => r + e.rain, 0) * 10, + wSpeed: wData.reduce( (r, e) => r + e.windSpeed, 0) / wData.length, + wDir: bestWindDirection, + wCardinal: bestCardinal + } + ]; + }, []); } - private createWeatherDataFromForecast(fd): WeatherData { - return {time: fd.date, minTemp: fd.minimumTemperature, - maxTemp: fd.maximumTemperature, relativeHumidity: fd.relativeHumidity, rain: fd.rain}; + private groupBy(items: any[], selector: (item) => any): any[] { + return items.reduce( + (result, item) => { + const group = selector(item); + return ({ + ...result, + [group]: [ + ...(result[group] || []), + item, + ], + });}, + {}, + ); } private removeUTCZ(dateFormat: string): string {