Asimuddin11 commited on
Commit
ef86bbb
·
verified ·
1 Parent(s): 8b391bb

Delete streamlit.py

Browse files
Files changed (1) hide show
  1. streamlit.py +0 -412
streamlit.py DELETED
@@ -1,412 +0,0 @@
1
- import streamlit as st
2
- import ee
3
- import geemap.foliumap as geemap
4
- import folium
5
- import pandas as pd
6
- import numpy as np
7
- import plotly.express as px
8
- import plotly.graph_objects as go
9
- from datetime import datetime, date
10
- import json
11
-
12
- # Configure Streamlit page
13
- st.set_page_config(
14
- page_title="Interactive Landsat 9 Analysis",
15
- page_icon="🛰️",
16
- layout="wide",
17
- initial_sidebar_state="expanded"
18
- )
19
-
20
- # Initialize Earth Engine function
21
- @st.cache_resource
22
- def init_ee_with_project(project_id=None):
23
- try:
24
- if project_id:
25
- ee.Initialize(project=project_id)
26
- else:
27
- ee.Initialize()
28
- return True, None
29
- except Exception as e:
30
- return False, str(e)
31
-
32
- # Main title and description
33
- st.title("🛰️ Interactive Landsat 9 OLI/TIRS Analysis")
34
- st.markdown("""
35
- This interactive application allows you to analyze Landsat 9 satellite imagery with various spectral indices
36
- and visualizations. Customize your analysis parameters using the sidebar controls.
37
- """)
38
-
39
- # Earth Engine initialization with project handling
40
- ee_initialized = False
41
-
42
- # Try to initialize without project first
43
- success, error = init_ee_with_project()
44
-
45
- if not success:
46
- st.warning("Earth Engine initialization failed. Please provide your Google Cloud Project ID.")
47
- st.info("""
48
- **To get your Project ID:**
49
- 1. Go to https://console.cloud.google.com/
50
- 2. Create a new project or select an existing one
51
- 3. Enable the Earth Engine API for your project
52
- 4. Copy the Project ID from the project selector
53
- """)
54
-
55
- project_id = st.text_input(
56
- "Enter your Google Cloud Project ID:",
57
- help="Find this in your Google Cloud Console dashboard"
58
- )
59
-
60
- if project_id:
61
- success, error = init_ee_with_project(project_id)
62
- if success:
63
- st.success(f"Successfully initialized Earth Engine with project: {project_id}")
64
- ee_initialized = True
65
- else:
66
- st.error(f"Failed to initialize with project {project_id}: {error}")
67
-
68
- if not ee_initialized:
69
- st.stop()
70
- else:
71
- ee_initialized = True
72
- st.success("Earth Engine initialized successfully!")
73
-
74
- # Sidebar controls
75
- st.sidebar.header("🎛️ Analysis Parameters")
76
-
77
- # Location settings
78
- st.sidebar.subheader("📍 Location Settings")
79
- center_lat = st.sidebar.number_input("Center Latitude", value=34.741, format="%.3f")
80
- center_lon = st.sidebar.number_input("Center Longitude", value=71.878, format="%.3f")
81
- buffer_size = st.sidebar.slider("Buffer Size (km)", min_value=10, max_value=100, value=50)
82
-
83
- # Date range settings
84
- st.sidebar.subheader("📅 Date Range")
85
- start_date = st.sidebar.date_input("Start Date", value=date(2022, 1, 1))
86
- end_date = st.sidebar.date_input("End Date", value=date(2022, 12, 31))
87
-
88
- # Cloud cover filter
89
- cloud_cover = st.sidebar.slider("Maximum Cloud Cover (%)", min_value=0, max_value=100, value=20)
90
-
91
- # Visualization options
92
- st.sidebar.subheader("🎨 Visualization Options")
93
- vis_options = {
94
- "True Color (432)": {"bands": ["B4", "B3", "B2"], "min": 8000, "max": 18000},
95
- "False Color (543)": {"bands": ["B5", "B4", "B3"], "min": 8000, "max": 20000},
96
- "Agriculture (654)": {"bands": ["B6", "B5", "B4"], "min": 8000, "max": 20000},
97
- "Geology (764)": {"bands": ["B7", "B6", "B4"], "min": 8000, "max": 20000},
98
- "Bathymetric (431)": {"bands": ["B4", "B3", "B1"], "min": 8000, "max": 18000}
99
- }
100
-
101
- selected_vis = st.sidebar.selectbox("Select Band Combination", list(vis_options.keys()))
102
-
103
- # Index calculations
104
- st.sidebar.subheader("📊 Spectral Indices")
105
- show_indices = st.sidebar.multiselect(
106
- "Select Indices to Display",
107
- ["NDVI", "EVI", "SAVI", "NDWI", "MNDWI", "NDBI", "NBR", "NDSI"],
108
- default=["NDVI", "NDWI"]
109
- )
110
-
111
- # Analysis function
112
- @st.cache_data
113
- def perform_analysis(lat, lon, buffer_km, start_dt, end_dt, max_cloud):
114
- # Define area of interest
115
- aoi = ee.Geometry.Point([lon, lat]).buffer(buffer_km * 1000)
116
-
117
- # Load Landsat 9 dataset
118
- dataset = ee.ImageCollection('LANDSAT/LC09/C02/T1') \
119
- .filterDate(start_dt.strftime('%Y-%m-%d'), end_dt.strftime('%Y-%m-%d')) \
120
- .filterBounds(aoi) \
121
- .filter(ee.Filter.lt('CLOUD_COVER', max_cloud)) \
122
- .sort('CLOUD_COVER')
123
-
124
- # Get dataset info
125
- size = dataset.size().getInfo()
126
-
127
- if size == 0:
128
- return None, None, "No images found for the specified criteria."
129
-
130
- # Create composite
131
- composite = dataset.median().clip(aoi)
132
-
133
- # Calculate indices
134
- indices = {}
135
-
136
- # Vegetation indices
137
- indices['NDVI'] = composite.normalizedDifference(['B5', 'B4']).rename('NDVI')
138
- indices['EVI'] = composite.expression(
139
- '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
140
- 'NIR': composite.select('B5'),
141
- 'RED': composite.select('B4'),
142
- 'BLUE': composite.select('B2')
143
- }).rename('EVI')
144
- indices['SAVI'] = composite.expression(
145
- '((NIR - RED) / (NIR + RED + 0.5)) * (1 + 0.5)', {
146
- 'NIR': composite.select('B5'),
147
- 'RED': composite.select('B4')
148
- }).rename('SAVI')
149
-
150
- # Water indices
151
- indices['NDWI'] = composite.normalizedDifference(['B3', 'B5']).rename('NDWI')
152
- indices['MNDWI'] = composite.normalizedDifference(['B3', 'B6']).rename('MNDWI')
153
-
154
- # Urban indices
155
- indices['NDBI'] = composite.normalizedDifference(['B6', 'B5']).rename('NDBI')
156
-
157
- # Burn index
158
- indices['NBR'] = composite.normalizedDifference(['B5', 'B7']).rename('NBR')
159
-
160
- # Snow index
161
- indices['NDSI'] = composite.normalizedDifference(['B3', 'B6']).rename('NDSI')
162
-
163
- # Calculate statistics
164
- stats = {}
165
- for name, index in indices.items():
166
- stat = index.reduceRegion(
167
- reducer=ee.Reducer.mean().combine(ee.Reducer.stdDev(), sharedInputs=True),
168
- geometry=aoi,
169
- scale=30,
170
- maxPixels=1e9
171
- ).getInfo()
172
- stats[name] = stat
173
-
174
- return composite, indices, stats, aoi, size
175
-
176
- # Run analysis button
177
- if st.sidebar.button("🚀 Run Analysis", type="primary"):
178
- with st.spinner("Analyzing Landsat 9 imagery..."):
179
- try:
180
- result = perform_analysis(
181
- center_lat, center_lon, buffer_size,
182
- start_date, end_date, cloud_cover
183
- )
184
-
185
- if result[0] is None:
186
- st.error(result[2])
187
- else:
188
- composite, indices, stats, aoi, image_count = result
189
- st.success(f"Analysis complete! Found {image_count} images.")
190
-
191
- # Store results in session state
192
- st.session_state.composite = composite
193
- st.session_state.indices = indices
194
- st.session_state.stats = stats
195
- st.session_state.aoi = aoi
196
- st.session_state.analysis_params = {
197
- 'lat': center_lat, 'lon': center_lon, 'buffer': buffer_size
198
- }
199
-
200
- except Exception as e:
201
- st.error(f"Analysis failed: {str(e)}")
202
-
203
- # Display results if analysis has been run
204
- if 'composite' in st.session_state:
205
- # Create tabs for different views
206
- tab1, tab2, tab3, tab4 = st.tabs(["🗺️ Interactive Map", "📊 Statistics", "📈 Charts", "📋 Data Export"])
207
-
208
- with tab1:
209
- st.subheader("Interactive Satellite Imagery Map")
210
-
211
- # Create the map
212
- Map = geemap.Map(center=[st.session_state.analysis_params['lat'],
213
- st.session_state.analysis_params['lon']], zoom=12)
214
-
215
- # Add selected visualization
216
- vis_params = vis_options[selected_vis]
217
- Map.addLayer(
218
- st.session_state.composite.select(vis_params['bands']),
219
- {
220
- 'min': vis_params['min'],
221
- 'max': vis_params['max'],
222
- 'bands': vis_params['bands']
223
- },
224
- selected_vis
225
- )
226
-
227
- # Add selected indices
228
- index_vis_params = {
229
- 'NDVI': {'min': -0.5, 'max': 0.8, 'palette': ['red', 'yellow', 'green']},
230
- 'EVI': {'min': -0.5, 'max': 0.8, 'palette': ['red', 'yellow', 'green']},
231
- 'SAVI': {'min': -0.5, 'max': 0.8, 'palette': ['red', 'yellow', 'green']},
232
- 'NDWI': {'min': -0.5, 'max': 0.5, 'palette': ['white', 'blue']},
233
- 'MNDWI': {'min': -0.5, 'max': 0.5, 'palette': ['white', 'blue']},
234
- 'NDBI': {'min': -0.5, 'max': 0.5, 'palette': ['blue', 'white', 'red']},
235
- 'NBR': {'min': -0.5, 'max': 0.5, 'palette': ['green', 'yellow', 'red']},
236
- 'NDSI': {'min': 0, 'max': 0.8, 'palette': ['red', 'yellow', 'white']}
237
- }
238
-
239
- for index_name in show_indices:
240
- if index_name in st.session_state.indices:
241
- Map.addLayer(
242
- st.session_state.indices[index_name].selfMask(),
243
- index_vis_params[index_name],
244
- index_name,
245
- False # Start with layer hidden
246
- )
247
-
248
- # Add AOI boundary
249
- Map.addLayer(st.session_state.aoi, {'color': 'yellow'}, 'Area of Interest')
250
-
251
- # Display the map
252
- Map.to_streamlit(height=600)
253
-
254
- with tab2:
255
- st.subheader("📊 Spectral Index Statistics")
256
-
257
- # Create statistics dataframe
258
- stats_data = []
259
- for index_name, stat_dict in st.session_state.stats.items():
260
- if index_name in show_indices:
261
- mean_key = f"{index_name}_mean"
262
- std_key = f"{index_name}_stdDev"
263
-
264
- mean_val = stat_dict.get(mean_key, 0)
265
- std_val = stat_dict.get(std_key, 0)
266
-
267
- stats_data.append({
268
- 'Index': index_name,
269
- 'Mean': round(mean_val, 4) if mean_val else 0,
270
- 'Standard Deviation': round(std_val, 4) if std_val else 0,
271
- 'Range': f"{round(mean_val - std_val, 4)} to {round(mean_val + std_val, 4)}" if mean_val and std_val else "N/A"
272
- })
273
-
274
- if stats_data:
275
- df_stats = pd.DataFrame(stats_data)
276
- st.dataframe(df_stats, use_container_width=True)
277
-
278
- # Create bar chart of mean values
279
- fig_bar = px.bar(
280
- df_stats,
281
- x='Index',
282
- y='Mean',
283
- title='Mean Values of Spectral Indices',
284
- color='Mean',
285
- color_continuous_scale='viridis'
286
- )
287
- fig_bar.update_layout(height=400)
288
- st.plotly_chart(fig_bar, use_container_width=True)
289
-
290
- with tab3:
291
- st.subheader("📈 Data Visualization")
292
-
293
- # Index interpretation guide
294
- with st.expander("📖 Index Interpretation Guide"):
295
- st.markdown("""
296
- **Vegetation Indices:**
297
- - **NDVI**: -1 to 1 (higher = more vegetation)
298
- - **EVI**: -1 to 1 (enhanced vegetation, reduces atmospheric effects)
299
- - **SAVI**: -1 to 1 (soil-adjusted vegetation index)
300
-
301
- **Water Indices:**
302
- - **NDWI**: -1 to 1 (higher = more water)
303
- - **MNDWI**: -1 to 1 (modified NDWI, better for water detection)
304
-
305
- **Urban/Built-up:**
306
- - **NDBI**: -1 to 1 (higher = more built-up areas)
307
-
308
- **Environmental:**
309
- - **NBR**: -1 to 1 (normalized burn ratio for fire detection)
310
- - **NDSI**: 0 to 1 (normalized difference snow index)
311
- """)
312
-
313
- # Create comparison chart if multiple indices selected
314
- if len(show_indices) > 1:
315
- comparison_data = []
316
- for index_name in show_indices:
317
- if index_name in st.session_state.stats:
318
- stat_dict = st.session_state.stats[index_name]
319
- mean_key = f"{index_name}_mean"
320
- mean_val = stat_dict.get(mean_key, 0)
321
- comparison_data.append({'Index': index_name, 'Mean Value': mean_val})
322
-
323
- if comparison_data:
324
- df_comparison = pd.DataFrame(comparison_data)
325
- fig_comparison = px.bar(
326
- df_comparison,
327
- x='Index',
328
- y='Mean Value',
329
- title='Spectral Index Comparison',
330
- color='Mean Value',
331
- color_continuous_scale='RdYlGn'
332
- )
333
- fig_comparison.update_layout(height=400)
334
- st.plotly_chart(fig_comparison, use_container_width=True)
335
-
336
- with tab4:
337
- st.subheader("📋 Data Export Options")
338
-
339
- col1, col2 = st.columns(2)
340
-
341
- with col1:
342
- st.markdown("**📊 Statistics Export**")
343
- if st.button("Download Statistics as CSV"):
344
- if 'stats' in st.session_state:
345
- stats_data = []
346
- for index_name, stat_dict in st.session_state.stats.items():
347
- mean_key = f"{index_name}_mean"
348
- std_key = f"{index_name}_stdDev"
349
- stats_data.append({
350
- 'Index': index_name,
351
- 'Mean': stat_dict.get(mean_key, 0),
352
- 'Standard_Deviation': stat_dict.get(std_key, 0)
353
- })
354
-
355
- df_export = pd.DataFrame(stats_data)
356
- csv = df_export.to_csv(index=False)
357
- st.download_button(
358
- label="📥 Download CSV",
359
- data=csv,
360
- file_name=f"landsat9_analysis_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
361
- mime="text/csv"
362
- )
363
-
364
- with col2:
365
- st.markdown("**🗺️ Map Export**")
366
- st.info("Use the map's built-in export tools to save visualizations as images.")
367
-
368
- # Analysis summary
369
- st.markdown("**📋 Analysis Summary**")
370
- summary_info = f"""
371
- - **Location**: {st.session_state.analysis_params['lat']:.3f}°N, {st.session_state.analysis_params['lon']:.3f}°E
372
- - **Buffer Size**: {st.session_state.analysis_params['buffer']} km
373
- - **Date Range**: {start_date} to {end_date}
374
- - **Cloud Cover**: ≤ {cloud_cover}%
375
- - **Selected Visualization**: {selected_vis}
376
- - **Active Indices**: {', '.join(show_indices)}
377
- """
378
- st.markdown(summary_info)
379
-
380
- else:
381
- # Instructions when no analysis has been run
382
- st.info("👈 Configure your analysis parameters in the sidebar and click 'Run Analysis' to get started!")
383
-
384
- # Feature overview
385
- st.markdown("""
386
- ## 🌟 Features
387
-
388
- **🛰️ Satellite Data Analysis**
389
- - Landsat 9 OLI/TIRS imagery (30m resolution)
390
- - Customizable date ranges and cloud cover filtering
391
- - Multiple band combinations for different applications
392
-
393
- **📊 Spectral Indices**
394
- - Vegetation: NDVI, EVI, SAVI
395
- - Water: NDWI, MNDWI
396
- - Urban: NDBI
397
- - Environmental: NBR (burn), NDSI (snow)
398
-
399
- **🎨 Interactive Visualizations**
400
- - True color, false color, and specialized composites
401
- - Statistical analysis and charting
402
- - Export capabilities for further analysis
403
-
404
- **🗺️ Interactive Mapping**
405
- - Zoom, pan, and layer control
406
- - Real-time visualization switching
407
- - Area of interest boundary display
408
- """)
409
-
410
- # Footer
411
- st.markdown("---")
412
- st.markdown("Built with ❤️ using Streamlit, Google Earth Engine, and geemap")