111 lines
3.2 KiB
Java
111 lines
3.2 KiB
Java
package eirb.pg203;
|
|
|
|
import org.json.JSONArray;
|
|
import org.json.JSONObject;
|
|
|
|
import eirb.pg203.WeatherData.Condition;
|
|
import eirb.pg203.utils.JSONFetcher;
|
|
|
|
import java.io.IOException;
|
|
import java.net.URI;
|
|
import java.net.URL;
|
|
import java.time.Instant;
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* WeatherAPI implementation
|
|
*/
|
|
public class WeatherAPI extends WeatherCachedAPI {
|
|
private final String weatherAPIKey;
|
|
private static final String forecastBaseURL = "https://api.weatherapi.com/v1/forecast.json";
|
|
|
|
WeatherAPI(String weatherAPIKey) {
|
|
this.weatherAPIKey = weatherAPIKey;
|
|
}
|
|
|
|
private JSONObject fetchWeather(int days, String city) throws IOException {
|
|
URL url = URI.create(
|
|
String.format(forecastBaseURL + "?key=%s&q=%s&days=%d",
|
|
this.weatherAPIKey,
|
|
city,
|
|
days
|
|
)
|
|
).toURL();
|
|
|
|
return JSONFetcher.fetch(url);
|
|
}
|
|
|
|
private static WeatherData.Condition getConditionFromString(String str) {
|
|
if (str.toLowerCase().contains("rain"))
|
|
return Condition.RAINY;
|
|
|
|
else if (str.toLowerCase().contains("partly"))
|
|
return Condition.PARTIAL;
|
|
|
|
else if (str.toLowerCase().contains("cloud"))
|
|
return Condition.CLOUDY;
|
|
|
|
return Condition.SUNNY;
|
|
}
|
|
|
|
private static WeatherData getWeatherDataFromForecast(JSONObject response, int day, String city) {
|
|
JSONObject forecastDay = response.getJSONObject("forecast").getJSONArray("forecastday").getJSONObject(day);
|
|
JSONArray forecastHour = forecastDay.getJSONArray("hour");
|
|
float temp_c = forecastDay.getJSONObject("day").getFloat("avgtemp_c");
|
|
|
|
// Calculates the mean for the day
|
|
float windSpeed = 0;
|
|
float windDirection = 0;
|
|
for (int i = 0 ; i < forecastHour.length() ; ++i)
|
|
{
|
|
windSpeed += forecastHour.getJSONObject(i).getFloat("wind_kph");
|
|
windDirection += forecastHour.getJSONObject(i).getFloat("wind_degree");
|
|
}
|
|
windSpeed /= forecastHour.length();
|
|
windDirection /= forecastHour.length();
|
|
|
|
String conditionStr = forecastDay.getJSONObject("day").getJSONObject("condition").getString("text");
|
|
|
|
return new WeatherData(
|
|
new City(city),
|
|
Instant.now(),
|
|
temp_c,
|
|
windSpeed,
|
|
windDirection,
|
|
getConditionFromString(conditionStr)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param day Day, 0 ≤ day ≤ 14
|
|
*/
|
|
@Override
|
|
public WeatherData getTemperature(int day, String cityName) throws IOException {
|
|
JSONObject result = fetchWeather(day+1, cityName);
|
|
return getWeatherDataFromForecast(result, day, cityName);
|
|
}
|
|
|
|
@Override
|
|
public WeatherData getTemperature(int day, int hour, String cityName) throws IOException{
|
|
return getTemperature(day, cityName);
|
|
}
|
|
|
|
public ArrayList<WeatherData> fetchTemperatures(int days, String cityName) throws IOException {
|
|
JSONObject result = fetchWeather(days, cityName);
|
|
ArrayList<WeatherData> weatherDatas = new ArrayList<>();
|
|
|
|
for (int day = 0; day < days; ++day) {
|
|
weatherDatas.add(
|
|
getWeatherDataFromForecast(result, day, cityName)
|
|
);
|
|
}
|
|
|
|
return weatherDatas;
|
|
}
|
|
|
|
@Override
|
|
public String getAPIName() {
|
|
return "WeatherAPI";
|
|
}
|
|
}
|