121 lines
3.3 KiB
Java
121 lines
3.3 KiB
Java
package eirb.pg203;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
import eirb.pg203.utils.JSONFetcher;
|
|
|
|
import java.io.IOException;
|
|
import java.net.URI;
|
|
import java.net.URL;
|
|
import java.time.Clock;
|
|
import java.time.Instant;
|
|
import java.util.ArrayList;
|
|
import java.util.Locale;
|
|
|
|
import eirb.pg203.WeatherData.Condition;
|
|
|
|
// https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&hourly=temperature_2m
|
|
|
|
/**
|
|
* OpenMeteo implementation
|
|
*/
|
|
public class OpenMeteo implements WeatherDataAPI {
|
|
private static final String forecastBaseURL = "https://api.open-meteo.com/v1/forecast";
|
|
private static final String dailyQuery = "weather_code,temperature_2m_max,temperature_2m_min,wind_speed_10m_max,wind_direction_10m_dominant";
|
|
JSONFetcher JSONFetcher = new JSONFetcher();
|
|
Clock clock = Clock.systemUTC();
|
|
|
|
/**
|
|
* Default constructor
|
|
*/
|
|
public OpenMeteo() {}
|
|
|
|
|
|
// https://www.nodc.noaa.gov/archive/arc0021/0002199/1.1/data/0-data/HTML/WMO-CODE/WMO4677.HTM
|
|
private JSONObject fetchWeather(int days, City city) throws IOException {
|
|
URL url = URI.create(
|
|
String.format(Locale.ENGLISH, forecastBaseURL + "?latitude=%.2f&longitude=%.2f&forecast_days=%d&daily=" + dailyQuery,
|
|
city.getCityCoords().getLat(),
|
|
city.getCityCoords().getLon(),
|
|
days
|
|
)
|
|
).toURL();
|
|
|
|
return JSONFetcher.fetch(url);
|
|
}
|
|
|
|
private static Condition getConditionFromCode(int WMOCode) {
|
|
// TODO Wesh Nemo c'est quoi cette merde ?
|
|
if (WMOCode == 2 )
|
|
return Condition.PARTIAL;
|
|
if (WMOCode < 20)
|
|
return Condition.SUNNY;
|
|
else if (WMOCode < 30)
|
|
return Condition.RAINY;
|
|
else if (WMOCode < 50)
|
|
return Condition.CLOUDY;
|
|
else
|
|
return Condition.RAINY;
|
|
}
|
|
|
|
|
|
private WeatherData getWeatherDataFromForecast(JSONObject response, int day, String city) {
|
|
JSONObject daily = response.getJSONObject("daily");
|
|
float max_temp = daily.getJSONArray("temperature_2m_max").getFloat(day);
|
|
float min_temp = daily.getJSONArray("temperature_2m_min").getFloat(day);
|
|
float temp_c = (min_temp + max_temp) / 2;
|
|
|
|
float windSpeed = daily.getJSONArray("wind_speed_10m_max").getFloat(day);
|
|
float windDirection = daily.getJSONArray("wind_direction_10m_dominant").getFloat(day);
|
|
int conditionCode = daily.getJSONArray("weather_code").getInt(day);
|
|
|
|
return new WeatherData(
|
|
new City(city),
|
|
Instant.now(clock),
|
|
temp_c,
|
|
windSpeed,
|
|
windDirection,
|
|
getConditionFromCode(conditionCode)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param day Day, 0 ≤ day ≤ 14
|
|
*/
|
|
@Override
|
|
public WeatherData getTemperature(int day, String city) throws IOException {
|
|
JSONObject result = fetchWeather(day + 1, new City(city));
|
|
|
|
return getWeatherDataFromForecast(result, day, city);
|
|
}
|
|
|
|
@Override
|
|
public WeatherData getTemperature(int day, int hour, String city) throws IOException{
|
|
return getTemperature(day, city);
|
|
}
|
|
|
|
@Override
|
|
public ArrayList<WeatherData> getTemperatures(int days, String city) throws IOException {
|
|
JSONObject result = fetchWeather(days, new City(city));
|
|
ArrayList<WeatherData> weatherDatas = new ArrayList<>();
|
|
|
|
for (int day = 0; day < days; ++day) {
|
|
weatherDatas.add(
|
|
getWeatherDataFromForecast(result, day, city)
|
|
);
|
|
}
|
|
|
|
return weatherDatas;
|
|
}
|
|
|
|
@Override
|
|
public String getAPIName() {
|
|
return "OpenMeteo";
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return this.getAPIName();
|
|
}
|
|
}
|