-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain
224 lines (175 loc) · 7.92 KB
/
Main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
// retreive weather data from API - this backend logic will fetch the latest weather
// data from the external API and return it. The GUI will
// display this data to the user
public class WeatherApp1 {
// fetch weather data for given location
public static JSONObject getWeatherData(String locationName){
// get location coordinates using the geolocation API
JSONArray locationData = getLocationData(locationName);
// extract latitude and longitude data
JSONObject location = (JSONObject) locationData.get(0);
double latitude = (double) location.get("latitude");
double longitude = (double) location.get("longitude");
// build API request URL with location coordinates
String urlString = "https://api.open-meteo.com/v1/forecast?" +
"latitude=" + latitude + "&longitude=" + longitude +
"&hourly=temperature_2m,relativehumidity_2m,weathercode,windspeed_10m&timezone=America%2FLos_Angeles";
try{
// call api and get response
HttpURLConnection conn = fetchApiResponse(urlString);
// check for response status
// 200 - means that the connection was a success
if(conn.getResponseCode() != 200){
System.out.println("Error: Could not connect to API");
return null;
}
// store resulting json data
StringBuilder resultJson = new StringBuilder();
Scanner scanner = new Scanner(conn.getInputStream());
while(scanner.hasNext()){
// read and store into the string builder
resultJson.append(scanner.nextLine());
}
// close scanner
scanner.close();
// close url connection
conn.disconnect();
// parse through our data
JSONParser parser = new JSONParser();
JSONObject resultJsonObj = (JSONObject) parser.parse(String.valueOf(resultJson));
// retrieve hourly data
JSONObject hourly = (JSONObject) resultJsonObj.get("hourly");
// we want to get the current hour's data
// so we need to get the index of our current hour
JSONArray time = (JSONArray) hourly.get("time");
int index = findIndexOfCurrentTime(time);
// get temperature
JSONArray temperatureData = (JSONArray) hourly.get("temperature_2m");
double temperature = (double) temperatureData.get(index);
// get weather code
JSONArray weathercode = (JSONArray) hourly.get("weathercode");
String weatherCondition = convertWeatherCode((long) weathercode.get(index));
// get humidity
JSONArray relativeHumidity = (JSONArray) hourly.get("relativehumidity_2m");
long humidity = (long) relativeHumidity.get(index);
// get windspeed
JSONArray windspeedData = (JSONArray) hourly.get("windspeed_10m");
double windspeed = (double) windspeedData.get(index);
// build the weather json data object that we are going to access in our frontend
JSONObject weatherData = new JSONObject();
weatherData.put("temperature", temperature);
weatherData.put("weather_condition", weatherCondition);
weatherData.put("humidity", humidity);
weatherData.put("windspeed", windspeed);
return weatherData;
}catch(Exception e){
e.printStackTrace();
}
return null;
}
// retrieves geographic coordinates for given location name
public static JSONArray getLocationData(String locationName){
// replace any whitespace in location name to + to adhere to API's request format
locationName = locationName.replaceAll(" ", "+");
// build API url with location parameter
String urlString = "https://geocoding-api.open-meteo.com/v1/search?name=" +
locationName + "&count=10&language=en&format=json";
try{
// call api and get a response
HttpURLConnection conn = fetchApiResponse(urlString);
// check response status
// 200 means successful connection
if(conn.getResponseCode() != 200){
System.out.println("Error: Could not connect to API");
return null;
}else{
// store the API results
StringBuilder resultJson = new StringBuilder();
Scanner scanner = new Scanner(conn.getInputStream());
// read and store the resulting json data into our string builder
while(scanner.hasNext()){
resultJson.append(scanner.nextLine());
}
// close scanner
scanner.close();
// close url connection
conn.disconnect();
// parse the JSON string into a JSON obj
JSONParser parser = new JSONParser();
JSONObject resultsJsonObj = (JSONObject) parser.parse(String.valueOf(resultJson));
// get the list of location data the API gtenerated from the lcoation name
JSONArray locationData = (JSONArray) resultsJsonObj.get("results");
return locationData;
}
}catch(Exception e){
e.printStackTrace();
}
// couldn't find location
return null;
}
private static HttpURLConnection fetchApiResponse(String urlString){
try{
// attempt to create connection
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// set request method to get
conn.setRequestMethod("GET");
// connect to our API
conn.connect();
return conn;
}catch(IOException e){
e.printStackTrace();
}
// could not make connection
return null;
}
private static int findIndexOfCurrentTime(JSONArray timeList){
String currentTime = getCurrentTime();
// iterate through the time list and see which one matches our current time
for(int i = 0; i < timeList.size(); i++){
String time = (String) timeList.get(i);
if(time.equalsIgnoreCase(currentTime)){
// return the index
return i;
}
}
return 0;
}
protected static String getCurrentTime(){
// get current date and time
LocalDateTime currentDateTime = LocalDateTime.now();
// format date to be 2023-09-02T00:00 (this is how is is read in the API)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH':00'");
// format and print the current date and time
String formattedDateTime = currentDateTime.format(formatter);
return formattedDateTime;
}
// convert the weather code to something more readable
private static String convertWeatherCode(long weathercode){
String weatherCondition = "";
if(weathercode == 0L){
// clear
weatherCondition = "Clear";
}else if(weathercode > 0L && weathercode <= 3L){
// cloudy
weatherCondition = "Cloudy";
}else if((weathercode >= 51L && weathercode <= 67L)
|| (weathercode >= 80L && weathercode <= 99L)){
// rain
weatherCondition = "Rain";
}else if(weathercode >= 71L && weathercode <= 77L){
// snow
weatherCondition = "Snow";
}
return weatherCondition;
}
}