aromidvar1355 commited on
Commit
d0caae6
·
verified ·
1 Parent(s): 52cdb9d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +186 -115
app.py CHANGED
@@ -9,6 +9,7 @@ from streamlit_folium import folium_static
9
  import numpy as np
10
  import time
11
  from datetime import datetime, timedelta
 
12
 
13
 
14
  # api keys
@@ -16,6 +17,7 @@ OPENWEATHER_API_KEY = "c6c267b301a145ddec9b381e7d87a5af"
16
  STORMGLASS_API_KEY = "bcabf6a8-0641-11f0-a4a9-0242ac130003-bcabf72a-0641-11f0-a4a9-0242ac130003"
17
 
18
 
 
19
  # Page Configuration
20
  st.set_page_config(page_title="Environmental Data Dashboard", layout="wide")
21
 
@@ -23,39 +25,75 @@ st.set_page_config(page_title="Environmental Data Dashboard", layout="wide")
23
  st.sidebar.title("🌍 Environmental Data Dashboard")
24
  data_source = st.sidebar.selectbox(
25
  "Select Data Source",
26
- ["OpenWeather", "Stormglass", "Air Quality", "Marine Forecast"]
27
  )
28
 
29
- # OpenWeather Data Fetching Function
30
- def fetch_openweather_data(lat, lon):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  try:
32
- # Current Weather
33
- current_url = f"https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={OPENWEATHER_API_KEY}&units=metric"
34
- current_response = requests.get(current_url)
35
- current_data = current_response.json()
36
-
37
- # Forecast
38
- forecast_url = f"https://api.openweathermap.org/data/2.5/forecast?lat={lat}&lon={lon}&appid={OPENWEATHER_API_KEY}&units=metric"
39
- forecast_response = requests.get(forecast_url)
40
- forecast_data = forecast_response.json()
41
-
42
- return current_data, forecast_data
43
- except Exception as e:
44
- st.error(f"Error fetching OpenWeather data: {e}")
45
- return None, None
 
 
 
46
 
47
  # Stormglass Data Fetching Function
48
- def fetch_stormglass_data(lat, lon, start_date, end_date):
 
 
 
49
  try:
 
 
 
 
50
  headers = {
51
  'Authorization': STORMGLASS_API_KEY
52
  }
 
 
53
  params = {
54
  'lat': lat,
55
  'lng': lon,
56
- 'params': 'waveHeight,windSpeed,windDirection,waterTemperature,airTemperature',
57
- 'start': start_date.isoformat(),
58
- 'end': end_date.isoformat()
 
 
 
 
 
 
 
59
  }
60
 
61
  response = requests.get(
@@ -65,18 +103,52 @@ def fetch_stormglass_data(lat, lon, start_date, end_date):
65
  )
66
 
67
  return response.json()
 
68
  except Exception as e:
69
  st.error(f"Error fetching Stormglass data: {e}")
70
  return None
71
 
72
- # Air Quality Data Fetching Function
73
- def fetch_air_quality_data(lat, lon):
 
 
 
74
  try:
75
- url = f"http://api.openweathermap.org/data/2.5/air_pollution?lat={lat}&lon={lon}&appid={OPENWEATHER_API_KEY}"
76
- response = requests.get(url)
77
- return response.json()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  except Exception as e:
79
- st.error(f"Error fetching Air Quality data: {e}")
80
  return None
81
 
82
  # Main Application Logic
@@ -87,11 +159,19 @@ def main():
87
 
88
  with col1:
89
  lat = st.number_input("Latitude", value=25.7617, format="%.4f")
90
- st.write(f"Selected Latitude: {lat}")
91
 
92
  with col2:
93
  lon = st.number_input("Longitude", value=-80.1918, format="%.4f")
94
- st.write(f"Selected Longitude: {lon}")
 
 
 
 
 
 
 
 
 
95
 
96
  # Map Visualization
97
  m = folium.Map(location=[lat, lon], zoom_start=10)
@@ -99,101 +179,90 @@ def main():
99
  folium_static(m)
100
 
101
  # Data Source Specific Sections
102
- if data_source == "OpenWeather":
103
- st.header("🌦️ Weather Data")
104
-
105
- # Fetch OpenWeather Data
106
- current_data, forecast_data = fetch_openweather_data(lat, lon)
107
 
108
- if current_data and forecast_data:
109
- # Current Weather Display
110
- st.subheader("Current Weather")
111
- col1, col2 = st.columns(2)
112
 
113
- with col1:
114
- st.metric("Temperature", f"{current_data['main']['temp']}°C")
115
- st.metric("Feels Like", f"{current_data['main']['feels_like']}°C")
116
-
117
- with col2:
118
- st.metric("Humidity", f"{current_data['main']['humidity']}%")
119
- st.metric("Wind Speed", f"{current_data['wind']['speed']} m/s")
120
-
121
- # Forecast Visualization
122
- st.subheader("5-Day Forecast")
123
- forecast_df = pd.DataFrame([
124
- {
125
- 'date': entry['dt_txt'],
126
- 'temperature': entry['main']['temp'],
127
- 'humidity': entry['main']['humidity'],
128
- 'description': entry['weather'][0]['description']
129
- }
130
- for entry in forecast_data['list']
131
- ])
132
-
133
- # Temperature Forecast Plot
134
- fig = px.line(
135
- forecast_df,
136
- x='date',
137
- y='temperature',
138
- title='Temperature Forecast'
139
- )
140
- st.plotly_chart(fig)
141
 
142
  elif data_source == "Stormglass":
143
- st.header("🌊 Marine Forecast")
144
-
145
- # Date Range Selection
146
- start_date = st.date_input("Start Date", datetime.now())
147
- end_date = st.date_input("End Date", datetime.now() + timedelta(days=5))
148
 
149
- # Fetch Stormglass Data
150
- marine_data = fetch_stormglass_data(lat, lon, start_date, end_date)
151
-
152
- if marine_data and 'hours' in marine_data:
153
- # Process Marine Data
154
- marine_df = pd.DataFrame([
155
- {
156
- 'time': hour['time'],
157
- 'wave_height': hour.get('waveHeight', {}).get('icon', np.nan),
158
- 'wind_speed': hour.get('windSpeed', {}).get('icon', np.nan),
159
- 'water_temp': hour.get('waterTemperature', {}).get('icon', np.nan)
160
- }
161
- for hour in marine_data['hours']
162
- ])
163
-
164
- # Marine Forecast Plots
165
- fig_wave = px.line(marine_df, x='time', y='wave_height', title='Wave Height')
166
- fig_wind = px.line(marine_df, x='time', y='wind_speed', title='Wind Speed')
167
 
168
- st.plotly_chart(fig_wave)
169
- st.plotly_chart(fig_wind)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
- elif data_source == "Air Quality":
172
- st.header("💨 Air Quality Index")
173
-
174
- # Fetch Air Quality Data
175
- air_quality_data = fetch_air_quality_data(lat, lon)
176
 
177
- if air_quality_data and 'list' in air_quality_data:
178
- aq_data = air_quality_data['list'][0]['main']
179
- components = air_quality_data['list'][0]['components']
180
-
181
- st.subheader("Air Quality Metrics")
182
- col1, col2 = st.columns(2)
183
-
184
- with col1:
185
- st.metric("AQI", aq_data['aqi'])
186
- st.metric("CO", f"{components['co']} μg/m³")
187
- st.metric("NO2", f"{components['no2']} μg/m³")
188
 
189
- with col2:
190
- st.metric("SO2", f"{components['so2']} μg/m³")
191
- st.metric("PM2.5", f"{components['pm2_5']} μg/m³")
192
- st.metric("PM10", f"{components['pm10']} μg/m³")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
- elif data_source == "Marine Forecast":
195
- st.header(" Advanced Marine Forecast")
196
- st.warning("Detailed marine forecast functionality to be implemented")
197
 
198
  # Footer
199
  st.sidebar.markdown("---")
@@ -202,4 +271,6 @@ st.sidebar.markdown("Powered by Streamlit & Open APIs")
202
 
203
  # Run the main application
204
  if __name__ == "__main__":
205
- main()
 
 
 
9
  import numpy as np
10
  import time
11
  from datetime import datetime, timedelta
12
+ import pytz
13
 
14
 
15
  # api keys
 
17
  STORMGLASS_API_KEY = "bcabf6a8-0641-11f0-a4a9-0242ac130003-bcabf72a-0641-11f0-a4a9-0242ac130003"
18
 
19
 
20
+
21
  # Page Configuration
22
  st.set_page_config(page_title="Environmental Data Dashboard", layout="wide")
23
 
 
25
  st.sidebar.title("🌍 Environmental Data Dashboard")
26
  data_source = st.sidebar.selectbox(
27
  "Select Data Source",
28
+ ["OpenWeather Historical", "Stormglass", "Solunar & Tide Data", "Air Quality"]
29
  )
30
 
31
+ # OpenWeather Historical Data Fetching Function
32
+ def fetch_openweather_historical_data(lat, lon, datetime_input):
33
+ """
34
+ Fetch historical weather data for a specific latitude, longitude, and datetime
35
+ """
36
+ # Validate datetime range (Time Machine API only supports past 5 days)
37
+ now = datetime.now()
38
+ five_days_ago = now - timedelta(days=5)
39
+
40
+ if datetime_input > now or datetime_input < five_days_ago:
41
+ st.error("Historical data is only available for the past 5 days.")
42
+ return None
43
+
44
+ # Convert datetime to Unix timestamp
45
+ timestamp = int(datetime_input.timestamp())
46
+
47
+ # Construct API URL
48
+ url = f"https://api.openweathermap.org/data/2.5/onecall/timemachine?lat={lat}&lon={lon}&dt={timestamp}&appid={OPENWEATHER_API_KEY}&units=metric"
49
+
50
  try:
51
+ # Send request to OpenWeather API
52
+ response = requests.get(url)
53
+ response.raise_for_status()
54
+
55
+ # Parse JSON response
56
+ data = response.json()
57
+
58
+ # Validate response structure
59
+ if not data or 'current' not in data:
60
+ st.error("No historical data available for the specified time.")
61
+ return None
62
+
63
+ return data
64
+
65
+ except requests.exceptions.RequestException as e:
66
+ st.error(f"Error fetching historical weather data: {e}")
67
+ return None
68
 
69
  # Stormglass Data Fetching Function
70
+ def fetch_stormglass_comprehensive_data(lat, lon, datetime_input):
71
+ """
72
+ Fetch comprehensive marine and environmental data from Stormglass
73
+ """
74
  try:
75
+ # Prepare start and end times (1 day range)
76
+ start_time = datetime_input - timedelta(hours=12)
77
+ end_time = datetime_input + timedelta(hours=12)
78
+
79
  headers = {
80
  'Authorization': STORMGLASS_API_KEY
81
  }
82
+
83
+ # Comprehensive parameters
84
  params = {
85
  'lat': lat,
86
  'lng': lon,
87
+ 'params': ','.join([
88
+ 'waveHeight', 'wavePeriod', 'waveDirection',
89
+ 'windSpeed', 'windDirection',
90
+ 'waterTemperature', 'airTemperature',
91
+ 'seaLevel', 'currentSpeed', 'currentDirection',
92
+ 'precipitation', 'cloudCover', 'visibility',
93
+ 'humidity', 'pressure'
94
+ ]),
95
+ 'start': start_time.isoformat(),
96
+ 'end': end_time.isoformat()
97
  }
98
 
99
  response = requests.get(
 
103
  )
104
 
105
  return response.json()
106
+
107
  except Exception as e:
108
  st.error(f"Error fetching Stormglass data: {e}")
109
  return None
110
 
111
+ # Solunar and Tide Data Fetching Function
112
+ def fetch_solunar_tide_data(lat, lon, datetime_input):
113
+ """
114
+ Fetch solunar and tide data for a specific location and time
115
+ """
116
  try:
117
+ # Stormglass Tide API
118
+ headers = {
119
+ 'Authorization': STORMGLASS_API_KEY
120
+ }
121
+
122
+ params = {
123
+ 'lat': lat,
124
+ 'lng': lon,
125
+ 'date': datetime_input.date().isoformat()
126
+ }
127
+
128
+ # Tide data
129
+ tide_response = requests.get(
130
+ 'https://api.stormglass.io/v2/tide/extremes/point',
131
+ headers=headers,
132
+ params=params
133
+ )
134
+
135
+ # Astronomy data (for sunrise/sunset)
136
+ astronomy_response = requests.get(
137
+ 'https://api.stormglass.io/v2/astronomy/point',
138
+ headers=headers,
139
+ params=params
140
+ )
141
+
142
+ tide_data = tide_response.json() if tide_response.status_code == 200 else None
143
+ astronomy_data = astronomy_response.json() if astronomy_response.status_code == 200 else None
144
+
145
+ return {
146
+ 'tide': tide_data,
147
+ 'astronomy': astronomy_data
148
+ }
149
+
150
  except Exception as e:
151
+ st.error(f"Error fetching Solunar and Tide data: {e}")
152
  return None
153
 
154
  # Main Application Logic
 
159
 
160
  with col1:
161
  lat = st.number_input("Latitude", value=25.7617, format="%.4f")
 
162
 
163
  with col2:
164
  lon = st.number_input("Longitude", value=-80.1918, format="%.4f")
165
+
166
+ # Date and Time inputs
167
+ col3, col4 = st.columns(2)
168
+ with col3:
169
+ input_date = st.date_input("Select Date", datetime.now())
170
+ with col4:
171
+ input_time = st.time_input("Select Time", datetime.now().time())
172
+
173
+ # Combine date and time
174
+ datetime_input = datetime.combine(input_date, input_time)
175
 
176
  # Map Visualization
177
  m = folium.Map(location=[lat, lon], zoom_start=10)
 
179
  folium_static(m)
180
 
181
  # Data Source Specific Sections
182
+ if data_source == "OpenWeather Historical":
183
+ st.header("🕰Historical Weather Data")
 
 
 
184
 
185
+ if st.button("Retrieve Historical Weather Data"):
186
+ historical_data = fetch_openweather_historical_data(lat, lon, datetime_input)
 
 
187
 
188
+ if historical_data:
189
+ current = historical_data.get('current', {})
190
+
191
+ st.subheader(f"Historical Weather on {datetime_input}")
192
+
193
+ col1, col2 = st.columns(2)
194
+
195
+ with col1:
196
+ st.metric("Temperature", f"{current.get('temp', 'N/A')}°C")
197
+ st.metric("Feels Like", f"{current.get('feels_like', 'N/A')}°C")
198
+ st.metric("Humidity", f"{current.get('humidity', 'N/A')}%")
199
+
200
+ with col2:
201
+ st.metric("Wind Speed", f"{current.get('wind_speed', 'N/A')} m/s")
202
+ st.metric("Wind Direction", f"{current.get('wind_deg', 'N/A')}°")
203
+ st.metric("Pressure", f"{current.get('pressure', 'N/A')} hPa")
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
  elif data_source == "Stormglass":
206
+ st.header("🌊 Comprehensive Marine Data")
 
 
 
 
207
 
208
+ if st.button("Retrieve Stormglass Data"):
209
+ stormglass_data = fetch_stormglass_comprehensive_data(lat, lon, datetime_input)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
 
211
+ if stormglass_data and 'hours' in stormglass_data:
212
+ # Process and display marine data
213
+ marine_df = pd.DataFrame([
214
+ {
215
+ 'time': pd.to_datetime(hour['time']),
216
+ 'wave_height': hour.get('waveHeight', {}).get('icon', np.nan),
217
+ 'wind_speed': hour.get('windSpeed', {}).get('icon', np.nan),
218
+ 'water_temp': hour.get('waterTemperature', {}).get('icon', np.nan),
219
+ 'current_speed': hour.get('currentSpeed', {}).get('icon', np.nan)
220
+ }
221
+ for hour in stormglass_data['hours']
222
+ ])
223
+
224
+ # Plots
225
+ fig1 = px.line(marine_df, x='time', y='wave_height', title='Wave Height')
226
+ fig2 = px.line(marine_df, x='time', y='wind_speed', title='Wind Speed')
227
+
228
+ st.plotly_chart(fig1)
229
+ st.plotly_chart(fig2)
230
 
231
+ elif data_source == "Solunar & Tide Data":
232
+ st.header("🌞 Solunar & Tide Information")
 
 
 
233
 
234
+ if st.button("Retrieve Solunar and Tide Data"):
235
+ solunar_tide_data = fetch_solunar_tide_data(lat, lon, datetime_input)
 
 
 
 
 
 
 
 
 
236
 
237
+ if solunar_tide_data:
238
+ # Tide Information
239
+ if solunar_tide_data['tide'] and 'data' in solunar_tide_data['tide']:
240
+ st.subheader("Tide Times")
241
+ tide_df = pd.DataFrame(solunar_tide_data['tide']['data'])
242
+
243
+ for _, tide in tide_df.iterrows():
244
+ st.write(f"**{tide['type'].capitalize()} Tide:**")
245
+ st.write(f"Time: {pd.to_datetime(tide['time']).strftime('%Y-%m-%d %H:%M:%S')}")
246
+ st.write(f"Height: {tide.get('height', 'N/A')} meters")
247
+
248
+ # Astronomy Information
249
+ if solunar_tide_data['astronomy'] and 'data' in solunar_tide_data['astronomy']:
250
+ st.subheader("Sun and Moon Information")
251
+ astro_data = solunar_tide_data['astronomy']['data']
252
+
253
+ col1, col2 = st.columns(2)
254
+
255
+ with col1:
256
+ st.metric("Sunrise", astro_data.get('sunrise', 'N/A'))
257
+ st.metric("Solar Noon", astro_data.get('solarNoon', 'N/A'))
258
+
259
+ with col2:
260
+ st.metric("Sunset", astro_data.get('sunset', 'N/A'))
261
+ st.metric("Day Length", astro_data.get('dayLength', 'N/A'))
262
 
263
+ elif data_source == "Air Quality":
264
+ st.header("💨 Air Quality Index")
265
+ st.warning("Air Quality data functionality to be implemented")
266
 
267
  # Footer
268
  st.sidebar.markdown("---")
 
271
 
272
  # Run the main application
273
  if __name__ == "__main__":
274
+ main()
275
+
276
+ Version 3 of 3