Weather forecast
Warning
This project aims at using third party software components. It may not be appropriate if you fancy “bottom up” coding yourself.
In this project you'll implement a terminal based weather forecast application. Consider the following invocation:
goik@goiki target> java -jar weather-1.0.jar Stuttgart ❶ 1 = Stadtkreis Stuttgart ❷ 2 = Regierungsbezirk Stuttgart 3 = Stuttgart 4 = Stuttgart Feuerbach 5 = Stuttgart Muehlhausen Bitte gültige Auswahl 1 bis 5 treffen:2 ❸ Vorhersage für Regierungsbezirk Stuttgart ❹ Dienstag, 15.05 23:00: 11°C, Leichter Regen Mittwoch, 16.05 02:00: 10°C, Leichter Regen 05:00: 10°C, Leichter Regen 08:00: 11°C, Leichter Regen ...
Command line argument Stuttgart acting as a search filter. |
|
The filter Stuttgart yields five matching towns / regions. |
|
User choosing second match. |
|
Forecast corresponding to Regierungsbezirk Stuttgart. |
The actual weather data is being provided by a web service:
https://api.openweathermap.org/data/2.5/forecast?lang=de& ❶ APPID=7cufdhdcgdhsgdhgfcgsdss67b3&units=metric&id=3214105 {"cod":"200","message":0.0042,"cnt":40,"list":[ ❷ {"dt":1526428800,"main":{"temp":10.29,"temp_min":10.29, "temp_max":12.45,"pressure":985.75,"sea_level":1027.48, "grnd_level":985.75,"humidity":80,"temp_kf":-2.16}, "weather":[{"id":500,"main":"Rain", "description":"Leichter Regen","icon":"10n"}],"clouds": {"all":88},"wind":{"speed":1.59,"deg":313.503},"rain": {"3h":0.315},"sys":{"pod":"n"},"dt_txt":"2018-05-16 00:00:00"}, {"dt":1526439600,"main": ...
An URL containing an id value corresponding to a uniquely defined town or region. We identify the following components:
|
|
|
cities.list.json.gz
providing cities [
{
"id": 2886241,
"name": "Regierungsbezirk Köln",
"country": "DE",
"coord": {
"lon": 7.16667,
"lat": 50.833328
}
},
{
"id": 3247452,
"name": "Kreis Euskirchen",
...
]
FileUtils.copyURLToFile(
"https://api.openweathermap.org/data/2.5/forecast...",
new File("weatherData.json"));
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
public class Cities {
static public final City[] cities;
...
}
@Test public void testParsedCityCount() {
Assert.assertEquals(209579, Cities.cities.length);
}
public class WeatherDataParser {
static public final Weather parse(final String jsonWeatherDataFilename)
throws IOException {
return ...;
}
}
@Test public void testParseWeatherData() {
...
Weather weather = WeatherDataParser.parse(
"src/main/resources/stuttgart.weather.json");
...
-
The application shall accept a command line parameter like e.g. «Stuttgart» to filter matching cities from
cities.list.json
. -
If a given filter matches multiple locations the user shall have an option for choosing the desired one.
-
The most recent city id value shall be cached in a file. Subsequent invocations without command line parameter shall provide a current forecast corresponding to this value.
-
Weather data belonging to a given id value shall be cached locally for 10 minutes. Subsequent weather queries within this period shall be read from cache rather than by accessing
https://api.openweathermap.org/...
.Provide logging to a file rather than to the console to avoid cluttering the user interface. Log cache handling.
-
Provide logging to a file rather than to the console to avoid cluttering the user interface.
-
Log cache handling.
main INFO weather.Forecast - Re-using cache file '/ma/goik/Forecast/6930414.json' from 196 seconds ago
Tip
See the related skeleton project.