Zeel commited on
Commit
4466df0
1 Parent(s): b206b8c

keep sentinel. Apply changes

Browse files
Files changed (3) hide show
  1. app.py +228 -166
  2. sandbox.ipynb +532 -17
  3. zonal_stats.csv +2 -2
app.py CHANGED
@@ -1,48 +1,19 @@
1
  import os
2
  import ee
3
  import json
 
4
  import geemap
5
  import geemap.foliumap as gee_folium
6
  import leafmap.foliumap as leaf_folium
7
  import streamlit as st
8
- from pandas import to_datetime, read_csv, merge, date_range, DateOffset
9
- from geopandas import read_file
10
  from shapely.ops import transform
11
  from functools import reduce
12
  import plotly.express as px
13
 
14
  st.set_page_config(layout="wide")
15
 
16
- ############################################
17
- # One time setup
18
- ############################################
19
-
20
-
21
- def initialize_ee():
22
- credentials_path = os.path.expanduser("~/.config/earthengine/credentials")
23
- if os.path.exists(credentials_path):
24
- pass # Earth Engine credentials already exist
25
- elif "EE" in os.environ: # write the credentials to the file
26
- ee_credentials = os.environ.get("EE")
27
- os.makedirs(os.path.dirname(credentials_path), exist_ok=True)
28
- with open(credentials_path, "w") as f:
29
- f.write(ee_credentials)
30
- else:
31
- raise ValueError(
32
- f"Earth Engine credentials not found at {credentials_path} or in the environment variable 'EE'"
33
- )
34
-
35
- ee.Initialize()
36
-
37
-
38
- if "ee_initialized" not in st.session_state:
39
- initialize_ee()
40
- st.session_state.ee_initialized = True
41
-
42
- if "wayback_mapping" not in st.session_state:
43
- with open("wayback_imagery.json") as f:
44
- st.session_state.wayback_mapping = json.load(f)
45
-
46
 
47
  ############################################
48
  # Functions
@@ -53,34 +24,60 @@ def shape_3d_to_2d(shape):
53
  else:
54
  return shape
55
 
56
-
57
  def preprocess_gdf(gdf):
58
  gdf = gdf.to_crs(epsg=4326)
59
- gdf = gdf[['Name', 'geometry']]
60
  gdf["geometry"] = gdf["geometry"].apply(shape_3d_to_2d)
61
  return gdf
62
 
63
-
64
  def calculate_ndvi(image, nir_band, red_band):
65
  nir = image.select(nir_band)
66
  red = image.select(red_band)
67
  ndvi = (nir.subtract(red)).divide(nir.add(red)).rename("NDVI")
68
  return image.addBands(ndvi)
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  def postprocess_df(df, name):
72
  df = df.T
73
  df = df.reset_index()
74
  ndvi_df = df[df["index"].str.contains("NDVI")]
75
- ndvi_df["index"] = to_datetime(ndvi_df["index"], format="%Y-%m_NDVI")
76
  ndvi_df = ndvi_df.rename(columns={"index": "Date", 0: name})
77
-
78
  cloud_mask_probability = df[df["index"].str.contains("MSK_CLDPRB")]
79
- cloud_mask_probability["index"] = to_datetime(cloud_mask_probability["index"], format="%Y-%m_MSK_CLDPRB")
80
- cloud_mask_probability = cloud_mask_probability.rename(columns={"index": "Date", 0: f"{name}_cloud_proba"})
 
 
 
 
81
  # normalize
82
- cloud_mask_probability[f"{name}_cloud_proba"] = cloud_mask_probability[f"{name}_cloud_proba"] / 100
83
- df = merge(ndvi_df, cloud_mask_probability, on="Date", how="outer")
 
 
84
  return df
85
 
86
 
@@ -88,6 +85,75 @@ def write_info(info):
88
  st.write(f"<span style='color:#00FF00;'>{info}</span>", unsafe_allow_html=True)
89
 
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  ############################################
92
  # App
93
  ############################################
@@ -96,166 +162,162 @@ def write_info(info):
96
  # make title in center
97
  st.markdown(
98
  f"""
99
- <h1 style="text-align: center;">Mean NDVI Calculator</h1>
100
  """,
101
  unsafe_allow_html=True,
102
  )
103
 
104
  # Input: Date and Cloud Cover
105
- col = st.columns(2)
106
- start_date = col[0].date_input("Start Date", value=to_datetime("2021-01-01"))
107
- end_date = col[1].date_input("End Date", value=to_datetime("2021-07-31"))
108
- start_date = start_date.strftime("%Y-%m")
109
- end_date = end_date.strftime("%Y-%m")
110
- # max_cloud_cover = st.number_input("Max Cloud Cover (in percentage)", value=5)
 
111
 
112
  # Input: GeoJSON/KML file
113
  uploaded_file = st.file_uploader("Upload KML/GeoJSON file", type=["geojson", "kml"])
114
  if uploaded_file is None:
115
  st.stop()
116
 
117
- file_name = uploaded_file.name
118
- gdf = read_file(uploaded_file)
119
- gdf = preprocess_gdf(gdf)
 
120
 
121
- selected_shape = st.selectbox("Select the geometry", gdf.Name.values)
122
- if selected_shape is None:
 
 
 
123
  st.stop()
124
 
125
- selected_shape = gdf[gdf.Name == selected_shape]
126
- ee_object = geemap.gdf_to_ee(selected_shape)
127
- write_info(f"Type of Geometry: {selected_shape.geometry.type.values[0]}")
 
 
128
 
 
129
  st.write("Select the satellite sources:")
130
- satellites = {
131
- "LANDSAT/LC08/C02/T1_TOA": {
132
- "selected": st.checkbox("LANDSAT/LC08/C02/T1_TOA", value=True),
133
- "nir_band": "B5",
134
- "red_band": "B4",
135
- "scale": 30,
136
- },
137
- "COPERNICUS/S2_SR_HARMONIZED": {
138
- "selected": st.checkbox("COPERNICUS/S2_SR_HARMONIZED", value=True),
139
- "nir_band": "B8",
140
- "red_band": "B4",
141
- "scale": 10,
142
- },
143
- }
144
 
 
145
  submit = st.button("Submit", use_container_width=True)
146
  if submit:
147
- if not any(satellites.values()):
148
  st.error("Please select at least one satellite source")
149
  st.stop()
150
 
151
  # Create month range
152
- dates = date_range(start_date, end_date, freq="MS").strftime("%Y-%m-%d").tolist()
153
  write_info(
154
  f"Start Date (inclusive): {start_date}, End Date (exclusive): {end_date}"
155
  )
156
-
157
- df_list = []
158
- collections = {}
159
  for satellite, attrs in satellites.items():
160
- if not attrs["selected"]:
161
  continue
162
- collection = ee.ImageCollection(satellite)
163
- collection = collection.filterBounds(ee_object)
164
- if satellite == "COPERNICUS/S2_SR_HARMONIZED":
165
- collection = collection.select([attrs["red_band"], attrs["nir_band"], "MSK_CLDPRB"])
166
- else:
167
- collection = collection.select([attrs["red_band"], attrs["nir_band"]])
168
- # collection = collection.filter(ee.Filter.lt(attrs["cloud_cover_var"], max_cloud_cover))
169
- collection = collection.filterDate(start_date, end_date)
170
- collection = collection.map(
171
- lambda image: calculate_ndvi(
172
- image, nir_band=attrs["nir_band"], red_band=attrs["red_band"]
173
- )
174
- )
175
- write_info(f"Number of images in {satellite}: {collection.size().getInfo()}")
176
-
177
- progress_bar = st.progress(0)
178
-
179
- def monthly_quality_mosaic(start, end, i):
180
- progress_bar.progress((i + 1) / (len(dates) - 1))
181
- collection_filtered = collection.filterDate(start, end)
182
- size = collection_filtered.size().getInfo()
183
- if size == 0:
184
- return None
185
- mosaic = collection_filtered.qualityMosaic("NDVI")
186
- month = to_datetime(start).strftime("%Y-%m")
187
- print(f"Processing {month} with {size} images")
188
- return mosaic.set("system:index", f"{month}")
189
-
190
- collection = [monthly_quality_mosaic(start, end, i) for i, (start, end) in enumerate(zip(dates[:-1], dates[1:]))]
191
- collection = list(filter(None, collection))
192
- collection = ee.ImageCollection(collection)
193
- collections[satellite] = collection
194
-
195
- save_name = satellite.replace("/", "_")
196
- geemap.zonal_stats(
197
- collection,#.select(["NDVI"]),
198
- ee_object,
199
- f"/tmp/{save_name}.csv",
200
- stat_type="mean",
201
- scale=attrs["scale"],
202
  )
203
- df = read_csv(f"/tmp/{save_name}.csv")
204
- df = postprocess_df(df, name=satellite)
205
- df_list.append(df)
206
-
207
- df = reduce(lambda left, right: merge(left, right, on="Date", how="outer"), df_list)
208
- df = df.sort_values("Date")
209
-
210
- # drop rows with all NaN values
211
- df = df.dropna(how="all")
212
- # drop columns with all NaN values
213
- df = df.dropna(axis=1, how="all")
214
- df = df.reset_index(drop=True)
215
-
216
- st.session_state.df = df
217
- st.session_state.collections = collections
218
-
219
- if "df" in st.session_state:
220
- df = st.session_state.df
221
- collections = st.session_state.collections
222
- st.write(df.applymap(lambda x: f"{x:.2f}" if isinstance(x, float) else x))
223
-
224
- fig = px.line(df, x="Date", y=df.columns[1:], title='Mean NDVI', markers=True)
225
- fig.update_yaxes(range=[0, 1])
226
  st.plotly_chart(fig)
227
-
228
  st.subheader("Visual Inspection")
229
- write_info(f"Centroid of the selected geometry: {selected_shape.geometry.centroid.values[0]}")
 
 
230
  cols = st.columns(2)
 
231
  with cols[0]:
232
- start_date = st.selectbox("Start Date", df.Date, index=0)
233
- start_date_index = df[df.Date == start_date].index[0].item()
234
  with cols[1]:
235
- end_date = st.selectbox("End Date", df.Date, index=len(df.Date) - 1)
236
- end_date_index = df[df.Date == end_date].index[0].item()
237
-
238
- for imagery in satellites:
239
- collection = collections[imagery]
240
- for col, date in zip(cols, [start_date, end_date]):
241
- date_index = df[df.Date == date].index[0].item()
242
- image = ee.Image(collections[imagery].toList(collection.size()).get(date_index))
243
- layer = gee_folium.ee_tile_layer(image, {"bands": ["NDVI"], "min": 0, "max": 1}, f"{imagery}_{date}")
244
 
 
 
 
 
 
245
  with col:
246
- m = leaf_folium.Map()
247
- m.add_layer(layer)
248
- m.add_gdf(selected_shape, layer_name="Selected Geometry")
249
- colors = ["#000000", "#FFFFFF"]
250
- m.add_colorbar(colors, vmin=0, vmax=1)
251
- st.write(f"{imagery} - {date}")
252
- m.to_streamlit()
253
-
254
- for col, date in zip(cols, [start_date, end_date]):
255
- esri_date = min(st.session_state.wayback_mapping.keys(), key=lambda x: abs(to_datetime(x) - date))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  with col:
257
  m = leaf_folium.Map()
258
- m.add_tile_layer(st.session_state.wayback_mapping[esri_date], name=f"Esri Wayback Imagery - {esri_date}", attribution="Esri")
259
- m.add_gdf(selected_shape, layer_name="Selected Geometry")
260
- st.write(f"Esri Wayback Imagery - {esri_date} (Closest to {date})")
261
- m.to_streamlit()
 
1
  import os
2
  import ee
3
  import json
4
+ import geojson
5
  import geemap
6
  import geemap.foliumap as gee_folium
7
  import leafmap.foliumap as leaf_folium
8
  import streamlit as st
9
+ import pandas as pd
10
+ import geopandas as gpd
11
  from shapely.ops import transform
12
  from functools import reduce
13
  import plotly.express as px
14
 
15
  st.set_page_config(layout="wide")
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  ############################################
19
  # Functions
 
24
  else:
25
  return shape
26
 
 
27
  def preprocess_gdf(gdf):
28
  gdf = gdf.to_crs(epsg=4326)
29
+ gdf = gdf[["Name", "geometry"]]
30
  gdf["geometry"] = gdf["geometry"].apply(shape_3d_to_2d)
31
  return gdf
32
 
 
33
  def calculate_ndvi(image, nir_band, red_band):
34
  nir = image.select(nir_band)
35
  red = image.select(red_band)
36
  ndvi = (nir.subtract(red)).divide(nir.add(red)).rename("NDVI")
37
  return image.addBands(ndvi)
38
 
39
+ def process_date(start_date, end_date, satellite):
40
+ try:
41
+ attrs = satellites[satellite]
42
+ collection = attrs["collection"]
43
+ collection = collection.filterBounds(ee_geometry)
44
+ collection = collection.filterDate(start_date, end_date)
45
+ mosaic = collection.qualityMosaic("NDVI")
46
+ fc = geemap.zonal_stats(
47
+ mosaic, ee_feature_collection, scale=attrs["scale"], return_fc=True
48
+ ).getInfo()
49
+ mean_ndvi = fc["features"][0]["properties"]["NDVI"]
50
+ if satellite == "COPERNICUS/S2_SR_HARMONIZED":
51
+ cloud_mask_probability = fc["features"][0]["properties"]["MSK_CLDPRB"] / 100
52
+ else:
53
+ cloud_mask_probability = None
54
+ except Exception as e:
55
+ print(e)
56
+ mosaic = None
57
+ mean_ndvi = None
58
+ cloud_mask_probability = None
59
+ return mosaic, mean_ndvi, cloud_mask_probability
60
+
61
 
62
  def postprocess_df(df, name):
63
  df = df.T
64
  df = df.reset_index()
65
  ndvi_df = df[df["index"].str.contains("NDVI")]
66
+ ndvi_df["index"] = pd.to_datetime(ndvi_df["index"], format="%Y-%m_NDVI")
67
  ndvi_df = ndvi_df.rename(columns={"index": "Date", 0: name})
68
+
69
  cloud_mask_probability = df[df["index"].str.contains("MSK_CLDPRB")]
70
+ cloud_mask_probability["index"] = pd.to_datetime(
71
+ cloud_mask_probability["index"], format="%Y-%m_MSK_CLDPRB"
72
+ )
73
+ cloud_mask_probability = cloud_mask_probability.rename(
74
+ columns={"index": "Date", 0: f"{name}_cloud_proba"}
75
+ )
76
  # normalize
77
+ cloud_mask_probability[f"{name}_cloud_proba"] = (
78
+ cloud_mask_probability[f"{name}_cloud_proba"] / 100
79
+ )
80
+ df = pd.merge(ndvi_df, cloud_mask_probability, on="Date", how="outer")
81
  return df
82
 
83
 
 
85
  st.write(f"<span style='color:#00FF00;'>{info}</span>", unsafe_allow_html=True)
86
 
87
 
88
+ ############################################
89
+ # One time setup
90
+ ############################################
91
+
92
+
93
+ def one_time_setup():
94
+ credentials_path = os.path.expanduser("~/.config/earthengine/credentials")
95
+ if os.path.exists(credentials_path):
96
+ pass # Earth Engine credentials already exist
97
+ elif "EE" in os.environ: # write the credentials to the file
98
+ ee_credentials = os.environ.get("EE")
99
+ os.makedirs(os.path.dirname(credentials_path), exist_ok=True)
100
+ with open(credentials_path, "w") as f:
101
+ f.write(ee_credentials)
102
+ else:
103
+ raise ValueError(
104
+ f"Earth Engine credentials not found at {credentials_path} or in the environment variable 'EE'"
105
+ )
106
+
107
+ ee.Initialize()
108
+
109
+ satellites = {
110
+ # "LANDSAT/LC08/C02/T1_TOA": {
111
+ # "scale": 30,
112
+ # "collection": ee.ImageCollection("LANDSAT/LC08/C02/T1_TOA")
113
+ # .select(["B2", "B3", "B4", "B5"], ["B", "G", "R", "NIR"])
114
+ # .map(lambda image: calculate_ndvi(image, nir_band="NIR", red_band="R")),
115
+ # },
116
+ "COPERNICUS/S2_SR_HARMONIZED": {
117
+ "scale": 10,
118
+ "collection": ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
119
+ .select(
120
+ ["B4", "B8", "MSK_CLDPRB", "TCI_R", "TCI_G", "TCI_B"],
121
+ ["Red", "NIR", "MSK_CLDPRB", "R", "G", "B"],
122
+ )
123
+ .map(lambda image: calculate_ndvi(image, nir_band="NIR", red_band="Red")),
124
+ },
125
+ # "LANDSAT/LC09/C02/T1_L2": {
126
+ # "scale": 30,
127
+ # "collection": ee.ImageCollection("LANDSAT/LC09/C02/T1_L2")
128
+ # .select(["SR_B2", "SR_B3", "SR_B4", "SR_B5"], ["B", "G", "R", "NIR"])
129
+ # .map(lambda image: calculate_ndvi(image, nir_band="NIR", red_band="R")),
130
+ # },
131
+ # "LANDSAT/LC08/C02/T1_L2": {
132
+ # "scale": 30,
133
+ # "collection": ee.ImageCollection("LANDSAT/LC08/C02/T1_L2")
134
+ # .select(["SR_B2", "SR_B3", "SR_B4", "SR_B5"], ["B", "G", "R", "NIR"])
135
+ # .map(lambda image: calculate_ndvi(image, nir_band="NIR", red_band="R")),
136
+ # },
137
+ # "LANDSAT/LE07/C02/T1_L2": {
138
+ # "scale": 30,
139
+ # "collection": ee.ImageCollection("LANDSAT/LE07/C02/T1_L2")
140
+ # .select(["SR_B2", "SR_B3", "SR_B4", "SR_B5"], ["B", "G", "R", "NIR"])
141
+ # .map(lambda image: calculate_ndvi(image, nir_band="NIR", red_band="R")),
142
+ # },
143
+ }
144
+ st.session_state.satellites = satellites
145
+ with open("wayback_imagery.json") as f:
146
+ st.session_state.wayback_mapping = json.load(f)
147
+
148
+
149
+ if "one_time_setup_done" not in st.session_state:
150
+ one_time_setup()
151
+ st.session_state.one_time_setup_done = True
152
+ else:
153
+ satellites = st.session_state.satellites
154
+ wayback_mapping = st.session_state.wayback_mapping
155
+
156
+
157
  ############################################
158
  # App
159
  ############################################
 
162
  # make title in center
163
  st.markdown(
164
  f"""
165
+ <h1 style="text-align: center;">NDVI Explorer</h1>
166
  """,
167
  unsafe_allow_html=True,
168
  )
169
 
170
  # Input: Date and Cloud Cover
171
+ col = st.columns(4)
172
+ start_year = col[0].selectbox("Start Year", list(range(2014, 2024)), index=8)
173
+ start_month = col[1].selectbox("Start Month", list(range(1, 13)), index=0)
174
+ end_year = col[2].selectbox("End Year", list(range(2014, 2024)), index=8)
175
+ end_month = col[3].selectbox("End Month", list(range(1, 13)), index=2)
176
+ start_date = f"{start_year}-{start_month:02d}"
177
+ end_date = f"{end_year}-{end_month:02d}"
178
 
179
  # Input: GeoJSON/KML file
180
  uploaded_file = st.file_uploader("Upload KML/GeoJSON file", type=["geojson", "kml"])
181
  if uploaded_file is None:
182
  st.stop()
183
 
184
+ gdf = preprocess_gdf(gpd.read_file(uploaded_file))
185
+
186
+ # Input: Geometry
187
+ selected_geometry = st.selectbox("Select the geometry", gdf.Name.values)
188
 
189
+ selected_geometry = gdf[gdf.Name == selected_geometry].iloc[0].geometry
190
+ if selected_geometry.type != "Polygon":
191
+ st.error(
192
+ f"Selected geometry is of type {selected_geometry.type}. Please provide a polygon geometry."
193
+ )
194
  st.stop()
195
 
196
+ # Derived Inputs
197
+ selected_geometry = selected_geometry.__geo_interface__
198
+ ee_geometry = ee.Geometry(selected_geometry)
199
+ ee_feature_collection = ee.FeatureCollection(ee_geometry)
200
+ feature_collection = geojson.FeatureCollection([{"type": "Feature", "geometry": selected_geometry, "properties": {}}])
201
 
202
+ # Input: Satellite Sources
203
  st.write("Select the satellite sources:")
204
+ satellite_selected = {}
205
+ for satellite in satellites:
206
+ satellite_selected[satellite] = st.checkbox(satellite, value=True)
 
 
 
 
 
 
 
 
 
 
 
207
 
208
+ # Submit
209
  submit = st.button("Submit", use_container_width=True)
210
  if submit:
211
+ if not any(satellite_selected.values()):
212
  st.error("Please select at least one satellite source")
213
  st.stop()
214
 
215
  # Create month range
216
+ dates = pd.date_range(start_date, end_date, freq="MS").strftime("%Y-%m").tolist()
217
  write_info(
218
  f"Start Date (inclusive): {start_date}, End Date (exclusive): {end_date}"
219
  )
220
+ result = {key: {} for key in satellites}
 
 
221
  for satellite, attrs in satellites.items():
222
+ if not satellite_selected[satellite]:
223
  continue
224
+
225
+ with st.spinner(f"Processing {satellite} ..."):
226
+ progress_bar = st.progress(0)
227
+ for i, (start, end) in enumerate(zip(dates[:-1], dates[1:])):
228
+ mosaic, mean_ndvi, cloud_proba = process_date(start, end, satellite)
229
+ result[satellite][start] = {
230
+ "mosaic": mosaic,
231
+ "mean_ndvi": mean_ndvi,
232
+ "cloud_mask_probability": cloud_proba,
233
+ }
234
+ progress_bar.progress((i + 1) / (len(dates) - 1))
235
+
236
+ st.session_state.result = result
237
+
238
+ if "result" in st.session_state:
239
+ result = st.session_state.result
240
+
241
+ df_list = []
242
+ for satellite, satellite_result in result.items():
243
+ satellite_df = pd.DataFrame(satellite_result).T
244
+ satellite_df.rename(
245
+ columns={
246
+ "mean_ndvi": f"NDVI_{satellite}",
247
+ "mosaic": f"Mosaic_{satellite}",
248
+ "cloud_mask_probability": f"Cloud_{satellite}",
249
+ },
250
+ inplace=True,
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  )
252
+ # drop rows with all NaN values
253
+ satellite_df = satellite_df.dropna(how="all")
254
+ # drop columns with all NaN values
255
+ satellite_df = satellite_df.dropna(axis=1, how="all")
256
+ df_list.append(satellite_df)
257
+
258
+ # merge outer on index of the dataframes
259
+ df = reduce(
260
+ lambda left, right: pd.merge(
261
+ left, right, left_index=True, right_index=True, how="outer"
262
+ ),
263
+ df_list,
264
+ )
265
+ df.reset_index(inplace=True)
266
+ df.index = pd.to_datetime(df["index"], format="%Y-%m")
267
+ for column in df.columns:
268
+ df[column] = pd.to_numeric(df[column], errors="ignore")
269
+
270
+ df_numeric = df.select_dtypes(include=["float64"])
271
+
272
+ fig = px.line(df, y=df_numeric.columns, title="Mean NDVI", markers=True)
273
+ fig.update_yaxes(range=[-1, 1])
 
274
  st.plotly_chart(fig)
275
+
276
  st.subheader("Visual Inspection")
277
+ _, lonlat = ee_geometry.centroid().getInfo().values()
278
+ lon, lat = lonlat
279
+ write_info(f"Centroid of the selected geometry (lat, lon): ({lat}, {lon})")
280
  cols = st.columns(2)
281
+ df_dates = df.index.strftime("%Y-%m").tolist()
282
  with cols[0]:
283
+ date_1 = st.selectbox("Month 1", df_dates, index=0)
 
284
  with cols[1]:
285
+ date_2 = st.selectbox("Month 2", df_dates, index=len(df.index) - 1)
 
 
 
 
 
 
 
 
286
 
287
+ for satellite in satellites:
288
+ for col, date in zip(cols, [date_1, date_2]):
289
+ if f"Mosaic_{satellite}" not in df.columns:
290
+ continue
291
+ mosaic = df.loc[pd.to_datetime(date), f"Mosaic_{satellite}"]
292
  with col:
293
+ maps = [leaf_folium.Map(), leaf_folium.Map()]
294
+ ndvi_layer = gee_folium.ee_tile_layer(mosaic, {"bands": ["NDVI"], "min": 0, "max": 1})
295
+
296
+ if satellite == "COPERNICUS/S2_SR_HARMONIZED":
297
+ min_all = 0
298
+ max_all = 255
299
+ else:
300
+ raise ValueError(f"Unknown satellite: {satellite}")
301
+ visual_layer = gee_folium.ee_tile_layer(mosaic, {"bands": ["R", "G", "B"], "min": min_all, "max": max_all})
302
+
303
+ maps[0].add_layer(
304
+ ndvi_layer,
305
+ )
306
+
307
+ maps[1].add_layer(
308
+ visual_layer,
309
+ )
310
+
311
+ for m, name in zip(maps, ["NDVI", "Visual"]):
312
+ m.add_geojson(feature_collection)
313
+ write_info(f"{name}: {satellite} - {date}")
314
+ m.to_streamlit()
315
+
316
+ for col, date in zip(cols, [date_1, date_2]):
317
+ esri_date = min(wayback_mapping.keys(), key=lambda x: abs(pd.to_datetime(x) - pd.to_datetime(date)))
318
  with col:
319
  m = leaf_folium.Map()
320
+ m.add_tile_layer(wayback_mapping[esri_date], name=f"Esri Wayback Imagery - {esri_date}", attribution="Esri")
321
+ m.add_geojson(feature_collection)
322
+ write_info(f"Visual Esri Wayback Basemap - {esri_date} (Closest to {date})")
323
+ m.to_streamlit()
sandbox.ipynb CHANGED
@@ -2,7 +2,7 @@
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
- "execution_count": 145,
6
  "metadata": {},
7
  "outputs": [
8
  {
@@ -45,12 +45,299 @@
45
  "import geemap\n",
46
  "import geopandas as gpd\n",
47
  "from shapely.ops import transform\n",
48
- "ee.Initialize()"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  ]
50
  },
51
  {
52
  "cell_type": "code",
53
- "execution_count": 146,
54
  "metadata": {},
55
  "outputs": [
56
  {
@@ -86,6 +373,128 @@
86
  },
87
  "metadata": {},
88
  "output_type": "display_data"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  }
90
  ],
91
  "source": [
@@ -98,13 +507,17 @@
98
  " return shape\n",
99
  "gdf['geometry'] = gdf['geometry'].apply(poly_3d_to_2d)\n",
100
  "gdf = gdf.to_crs(epsg=4326)\n",
101
- "first_item = gdf.iloc[0:1]\n",
102
- "ee_object = geemap.gdf_to_ee(first_item)"
 
 
 
 
103
  ]
104
  },
105
  {
106
  "cell_type": "code",
107
- "execution_count": 120,
108
  "metadata": {},
109
  "outputs": [
110
  {
@@ -145,14 +558,18 @@
145
  "name": "stdout",
146
  "output_type": "stream",
147
  "text": [
148
- "Number of images in the collection: 2\n"
149
  ]
150
  }
151
  ],
152
  "source": [
153
- "dataset = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA').filterBounds(ee_object).filterDate('2023-01-01', '2023-01-31')\n",
154
- "true_color_432 = dataset.select(['B4', 'B3', 'B2'])\n",
155
- "print(\"Number of images in the collection: \", true_color_432.size().getInfo())"
 
 
 
 
156
  ]
157
  },
158
  {
@@ -217,7 +634,7 @@
217
  },
218
  {
219
  "cell_type": "code",
220
- "execution_count": 74,
221
  "metadata": {},
222
  "outputs": [
223
  {
@@ -258,16 +675,114 @@
258
  "name": "stdout",
259
  "output_type": "stream",
260
  "text": [
261
- "Computing statistics ...\n",
262
- "Generating URL ...\n",
263
- "Downloading data from https://earthengine.googleapis.com/v1/projects/815228341823/tables/8a81a210a87d3b3a27187b606616f13c-f5c9d2fc785b6f388b63270382c578e4:getFeatures\n",
264
- "Please wait ...\n",
265
- "Data downloaded to /home/patel_zeel/Mean_NDVI/zonal_stats.csv\n"
266
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  }
268
  ],
269
  "source": [
270
- "features = geemap.zonal_stats(dataset.qualityMosaic(\"B4\").select(\"B4\"), ee_object, statistics_type='mean', scale=10)"
271
  ]
272
  },
273
  {
 
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
+ "execution_count": 11,
6
  "metadata": {},
7
  "outputs": [
8
  {
 
45
  "import geemap\n",
46
  "import geopandas as gpd\n",
47
  "from shapely.ops import transform\n",
48
+ "ee.Initialize()\n",
49
+ "\n",
50
+ "import pandas as pd"
51
+ ]
52
+ },
53
+ {
54
+ "cell_type": "code",
55
+ "execution_count": 12,
56
+ "metadata": {},
57
+ "outputs": [
58
+ {
59
+ "data": {
60
+ "text/html": [
61
+ "\n",
62
+ " <style>\n",
63
+ " .geemap-dark {\n",
64
+ " --jp-widgets-color: white;\n",
65
+ " --jp-widgets-label-color: white;\n",
66
+ " --jp-ui-font-color1: white;\n",
67
+ " --jp-layout-color2: #454545;\n",
68
+ " background-color: #383838;\n",
69
+ " }\n",
70
+ "\n",
71
+ " .geemap-dark .jupyter-button {\n",
72
+ " --jp-layout-color3: #383838;\n",
73
+ " }\n",
74
+ "\n",
75
+ " .geemap-colab {\n",
76
+ " background-color: var(--colab-primary-surface-color, white);\n",
77
+ " }\n",
78
+ "\n",
79
+ " .geemap-colab .jupyter-button {\n",
80
+ " --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
81
+ " }\n",
82
+ " </style>\n",
83
+ " "
84
+ ],
85
+ "text/plain": [
86
+ "<IPython.core.display.HTML object>"
87
+ ]
88
+ },
89
+ "metadata": {},
90
+ "output_type": "display_data"
91
+ }
92
+ ],
93
+ "source": [
94
+ "import geemap.foliumap as gee_folium"
95
+ ]
96
+ },
97
+ {
98
+ "cell_type": "code",
99
+ "execution_count": 14,
100
+ "metadata": {},
101
+ "outputs": [
102
+ {
103
+ "data": {
104
+ "text/html": [
105
+ "\n",
106
+ " <style>\n",
107
+ " .geemap-dark {\n",
108
+ " --jp-widgets-color: white;\n",
109
+ " --jp-widgets-label-color: white;\n",
110
+ " --jp-ui-font-color1: white;\n",
111
+ " --jp-layout-color2: #454545;\n",
112
+ " background-color: #383838;\n",
113
+ " }\n",
114
+ "\n",
115
+ " .geemap-dark .jupyter-button {\n",
116
+ " --jp-layout-color3: #383838;\n",
117
+ " }\n",
118
+ "\n",
119
+ " .geemap-colab {\n",
120
+ " background-color: var(--colab-primary-surface-color, white);\n",
121
+ " }\n",
122
+ "\n",
123
+ " .geemap-colab .jupyter-button {\n",
124
+ " --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
125
+ " }\n",
126
+ " </style>\n",
127
+ " "
128
+ ],
129
+ "text/plain": [
130
+ "<IPython.core.display.HTML object>"
131
+ ]
132
+ },
133
+ "metadata": {},
134
+ "output_type": "display_data"
135
+ }
136
+ ],
137
+ "source": [
138
+ "m = gee_folium.Map()"
139
+ ]
140
+ },
141
+ {
142
+ "cell_type": "code",
143
+ "execution_count": 24,
144
+ "metadata": {},
145
+ "outputs": [
146
+ {
147
+ "data": {
148
+ "text/html": [
149
+ "\n",
150
+ " <style>\n",
151
+ " .geemap-dark {\n",
152
+ " --jp-widgets-color: white;\n",
153
+ " --jp-widgets-label-color: white;\n",
154
+ " --jp-ui-font-color1: white;\n",
155
+ " --jp-layout-color2: #454545;\n",
156
+ " background-color: #383838;\n",
157
+ " }\n",
158
+ "\n",
159
+ " .geemap-dark .jupyter-button {\n",
160
+ " --jp-layout-color3: #383838;\n",
161
+ " }\n",
162
+ "\n",
163
+ " .geemap-colab {\n",
164
+ " background-color: var(--colab-primary-surface-color, white);\n",
165
+ " }\n",
166
+ "\n",
167
+ " .geemap-colab .jupyter-button {\n",
168
+ " --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
169
+ " }\n",
170
+ " </style>\n",
171
+ " "
172
+ ],
173
+ "text/plain": [
174
+ "<IPython.core.display.HTML object>"
175
+ ]
176
+ },
177
+ "metadata": {},
178
+ "output_type": "display_data"
179
+ },
180
+ {
181
+ "data": {
182
+ "text/plain": [
183
+ "2.75e-05"
184
+ ]
185
+ },
186
+ "execution_count": 24,
187
+ "metadata": {},
188
+ "output_type": "execute_result"
189
+ }
190
+ ],
191
+ "source": [
192
+ "2.75e-05"
193
+ ]
194
+ },
195
+ {
196
+ "cell_type": "code",
197
+ "execution_count": 15,
198
+ "metadata": {},
199
+ "outputs": [
200
+ {
201
+ "data": {
202
+ "text/html": [
203
+ "\n",
204
+ " <style>\n",
205
+ " .geemap-dark {\n",
206
+ " --jp-widgets-color: white;\n",
207
+ " --jp-widgets-label-color: white;\n",
208
+ " --jp-ui-font-color1: white;\n",
209
+ " --jp-layout-color2: #454545;\n",
210
+ " background-color: #383838;\n",
211
+ " }\n",
212
+ "\n",
213
+ " .geemap-dark .jupyter-button {\n",
214
+ " --jp-layout-color3: #383838;\n",
215
+ " }\n",
216
+ "\n",
217
+ " .geemap-colab {\n",
218
+ " background-color: var(--colab-primary-surface-color, white);\n",
219
+ " }\n",
220
+ "\n",
221
+ " .geemap-colab .jupyter-button {\n",
222
+ " --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
223
+ " }\n",
224
+ " </style>\n",
225
+ " "
226
+ ],
227
+ "text/plain": [
228
+ "<IPython.core.display.HTML object>"
229
+ ]
230
+ },
231
+ "metadata": {},
232
+ "output_type": "display_data"
233
+ },
234
+ {
235
+ "name": "stdout",
236
+ "output_type": "stream",
237
+ "text": [
238
+ "\u001b[0;31mSignature:\u001b[0m\n",
239
+ "\u001b[0mm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maddLayer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n",
240
+ "\u001b[0;34m\u001b[0m \u001b[0mee_object\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
241
+ "\u001b[0;34m\u001b[0m \u001b[0mvis_params\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
242
+ "\u001b[0;34m\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Layer untitled'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
243
+ "\u001b[0;34m\u001b[0m \u001b[0mshown\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
244
+ "\u001b[0;34m\u001b[0m \u001b[0mopacity\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1.0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
245
+ "\u001b[0;34m\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
246
+ "\u001b[0;34m\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
247
+ "\u001b[0;31mSource:\u001b[0m \n",
248
+ " \u001b[0;32mdef\u001b[0m \u001b[0madd_layer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n",
249
+ "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
250
+ "\u001b[0;34m\u001b[0m \u001b[0mee_object\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
251
+ "\u001b[0;34m\u001b[0m \u001b[0mvis_params\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
252
+ "\u001b[0;34m\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Layer untitled\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
253
+ "\u001b[0;34m\u001b[0m \u001b[0mshown\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
254
+ "\u001b[0;34m\u001b[0m \u001b[0mopacity\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1.0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
255
+ "\u001b[0;34m\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
256
+ "\u001b[0;34m\u001b[0m \u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n",
257
+ "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Adds a given EE object to the map as a layer.\u001b[0m\n",
258
+ "\u001b[0;34m\u001b[0m\n",
259
+ "\u001b[0;34m Args:\u001b[0m\n",
260
+ "\u001b[0;34m ee_object (Collection|Feature|Image|MapId): The object to add to the map.\u001b[0m\n",
261
+ "\u001b[0;34m vis_params (dict, optional): The visualization parameters. Defaults to {}.\u001b[0m\n",
262
+ "\u001b[0;34m name (str, optional): The name of the layer. Defaults to 'Layer untitled'.\u001b[0m\n",
263
+ "\u001b[0;34m shown (bool, optional): A flag indicating whether the layer should be on by default. Defaults to True.\u001b[0m\n",
264
+ "\u001b[0;34m opacity (float, optional): The layer's opacity represented as a number between 0 and 1. Defaults to 1.\u001b[0m\n",
265
+ "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n",
266
+ "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n",
267
+ "\u001b[0;34m\u001b[0m \u001b[0mlayer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mEEFoliumTileLayer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mee_object\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvis_params\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshown\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mopacity\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n",
268
+ "\u001b[0;34m\u001b[0m \u001b[0mlayer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n",
269
+ "\u001b[0;34m\u001b[0m \u001b[0marc_add_layer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlayer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0murl_format\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshown\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mopacity\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
270
+ "\u001b[0;31mFile:\u001b[0m /opt/anaconda3/envs/zeel_py310/lib/python3.10/site-packages/geemap/foliumap.py\n",
271
+ "\u001b[0;31mType:\u001b[0m method"
272
+ ]
273
+ }
274
+ ],
275
+ "source": [
276
+ "m.addLayer??"
277
+ ]
278
+ },
279
+ {
280
+ "cell_type": "code",
281
+ "execution_count": 5,
282
+ "metadata": {},
283
+ "outputs": [
284
+ {
285
+ "data": {
286
+ "text/html": [
287
+ "\n",
288
+ " <style>\n",
289
+ " .geemap-dark {\n",
290
+ " --jp-widgets-color: white;\n",
291
+ " --jp-widgets-label-color: white;\n",
292
+ " --jp-ui-font-color1: white;\n",
293
+ " --jp-layout-color2: #454545;\n",
294
+ " background-color: #383838;\n",
295
+ " }\n",
296
+ "\n",
297
+ " .geemap-dark .jupyter-button {\n",
298
+ " --jp-layout-color3: #383838;\n",
299
+ " }\n",
300
+ "\n",
301
+ " .geemap-colab {\n",
302
+ " background-color: var(--colab-primary-surface-color, white);\n",
303
+ " }\n",
304
+ "\n",
305
+ " .geemap-colab .jupyter-button {\n",
306
+ " --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
307
+ " }\n",
308
+ " </style>\n",
309
+ " "
310
+ ],
311
+ "text/plain": [
312
+ "<IPython.core.display.HTML object>"
313
+ ]
314
+ },
315
+ "metadata": {},
316
+ "output_type": "display_data"
317
+ },
318
+ {
319
+ "data": {
320
+ "text/plain": [
321
+ "Index(['2023-01', '2023-02', '2023-03', '2023-04', '2023-05', '2023-06',\n",
322
+ " '2023-07', '2023-08', '2023-09', '2023-10', '2023-11', '2023-12',\n",
323
+ " '2024-01'],\n",
324
+ " dtype='object')"
325
+ ]
326
+ },
327
+ "execution_count": 5,
328
+ "metadata": {},
329
+ "output_type": "execute_result"
330
+ }
331
+ ],
332
+ "source": [
333
+ "start = \"2023-01\"\n",
334
+ "end = \"2024-01\"\n",
335
+ "pd.date_range(start, end, freq='MS').strftime(\"%Y-%m\")"
336
  ]
337
  },
338
  {
339
  "cell_type": "code",
340
+ "execution_count": 6,
341
  "metadata": {},
342
  "outputs": [
343
  {
 
373
  },
374
  "metadata": {},
375
  "output_type": "display_data"
376
+ },
377
+ {
378
+ "name": "stdout",
379
+ "output_type": "stream",
380
+ "text": [
381
+ "{'type': 'Polygon', 'coordinates': (((73.19791470947145, 24.01977640858627), (73.1951165609439, 24.01754094149261), (73.1955205367043, 24.01738340683521), (73.19480033400262, 24.01523619312771), (73.19463695073262, 24.01440311871703), (73.19454286010809, 24.0139003560814), (73.1942443392165, 24.0126807914708), (73.1942341944796, 24.0126863557728), (73.19653511275247, 24.01252023885471), (73.19648432210984, 24.01217871972386), (73.19764861281237, 24.01199930187962), (73.1981728693097, 24.01433254741455), (73.1986819814156, 24.01611200638915), (73.19959745133227, 24.01895266153662), (73.19791470947145, 24.01977640858627)),)}\n",
382
+ "<class 'dict'>\n"
383
+ ]
384
+ },
385
+ {
386
+ "data": {
387
+ "text/html": [
388
+ "<div><style>:root {\n",
389
+ " --font-color-primary: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
390
+ " --font-color-secondary: var(--jp-content-font-color2, rgba(0, 0, 0, 0.6));\n",
391
+ " --font-color-accent: rgba(123, 31, 162, 1);\n",
392
+ " --border-color: var(--jp-border-color2, #e0e0e0);\n",
393
+ " --background-color: var(--jp-layout-color0, white);\n",
394
+ " --background-color-row-even: var(--jp-layout-color1, white);\n",
395
+ " --background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
396
+ "}\n",
397
+ "\n",
398
+ "html[theme=\"dark\"],\n",
399
+ "body[data-theme=\"dark\"],\n",
400
+ "body.vscode-dark {\n",
401
+ " --font-color-primary: rgba(255, 255, 255, 1);\n",
402
+ " --font-color-secondary: rgba(255, 255, 255, 0.6);\n",
403
+ " --font-color-accent: rgb(173, 132, 190);\n",
404
+ " --border-color: #2e2e2e;\n",
405
+ " --background-color: #111111;\n",
406
+ " --background-color-row-even: #111111;\n",
407
+ " --background-color-row-odd: #313131;\n",
408
+ "}\n",
409
+ "\n",
410
+ ".ee {\n",
411
+ " padding: 1em;\n",
412
+ " line-height: 1.5em;\n",
413
+ " min-width: 300px;\n",
414
+ " max-width: 1200px;\n",
415
+ " overflow-y: scroll;\n",
416
+ " max-height: 600px;\n",
417
+ " border: 1px solid var(--border-color);\n",
418
+ " font-family: monospace;\n",
419
+ "}\n",
420
+ "\n",
421
+ ".ee li {\n",
422
+ " list-style-type: none;\n",
423
+ "}\n",
424
+ "\n",
425
+ ".ee ul {\n",
426
+ " padding-left: 1.5em !important;\n",
427
+ " margin: 0;\n",
428
+ "}\n",
429
+ "\n",
430
+ ".ee > ul {\n",
431
+ " padding-left: 0 !important;\n",
432
+ "}\n",
433
+ "\n",
434
+ ".ee-open,\n",
435
+ ".ee-shut {\n",
436
+ " color: var(--font-color-secondary);\n",
437
+ " cursor: pointer;\n",
438
+ " margin: 0;\n",
439
+ "}\n",
440
+ "\n",
441
+ ".ee-open:hover,\n",
442
+ ".ee-shut:hover {\n",
443
+ " color: var(--font-color-primary);\n",
444
+ "}\n",
445
+ "\n",
446
+ ".ee-k {\n",
447
+ " color: var(--font-color-accent);\n",
448
+ " margin-right: 6px;\n",
449
+ "}\n",
450
+ "\n",
451
+ ".ee-v {\n",
452
+ " color: var(--font-color-primary);\n",
453
+ "}\n",
454
+ "\n",
455
+ ".ee-toggle {\n",
456
+ " display: none;\n",
457
+ "}\n",
458
+ "\n",
459
+ ".ee-shut + ul {\n",
460
+ " display: none;\n",
461
+ "}\n",
462
+ "\n",
463
+ ".ee-open + ul {\n",
464
+ " display: block;\n",
465
+ "}\n",
466
+ "\n",
467
+ ".ee-shut::before {\n",
468
+ " display: inline-block;\n",
469
+ " content: \"▼\";\n",
470
+ " margin-right: 6px;\n",
471
+ " transform: rotate(-90deg);\n",
472
+ " transition: transform 0.2s;\n",
473
+ "}\n",
474
+ "\n",
475
+ ".ee-open::before {\n",
476
+ " transform: rotate(0deg);\n",
477
+ " display: inline-block;\n",
478
+ " content: \"▼\";\n",
479
+ " margin-right: 6px;\n",
480
+ " transition: transform 0.2s;\n",
481
+ "}\n",
482
+ "</style><div class='ee'><ul><li><label class='ee-shut'>FeatureCollection (1 element, 1 column)<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>type:</span><span class='ee-v'>FeatureCollection</span></li><li><label class='ee-shut'>columns: Object (1 property)<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>system:index:</span><span class='ee-v'>String</span></li></ul></li><li><label class='ee-shut'>features: List (1 element)<input type='checkbox' class='ee-toggle'></label><ul><li><label class='ee-shut'>0: Feature (Polygon, 0 properties)<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>type:</span><span class='ee-v'>Feature</span></li><li><span class='ee-k'>id:</span><span class='ee-v'>0</span></li><li><label class='ee-shut'>geometry: Polygon (15 vertices)<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>type:</span><span class='ee-v'>Polygon</span></li><li><label class='ee-shut'>coordinates: List (1 element)<input type='checkbox' class='ee-toggle'></label><ul><li><label class='ee-shut'>0: List (15 elements)<input type='checkbox' class='ee-toggle'></label><ul><li><label class='ee-shut'>0: [73.19791470947145, 24.01977640858627]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.19791470947145</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01977640858627</span></li></ul></li><li><label class='ee-shut'>1: [73.1951165609439, 24.01754094149261]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.1951165609439</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01754094149261</span></li></ul></li><li><label class='ee-shut'>2: [73.1955205367043, 24.01738340683521]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.1955205367043</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01738340683521</span></li></ul></li><li><label class='ee-shut'>3: [73.19480033400262, 24.01523619312771]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.19480033400262</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01523619312771</span></li></ul></li><li><label class='ee-shut'>4: [73.19463695073262, 24.01440311871703]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.19463695073262</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01440311871703</span></li></ul></li><li><label class='ee-shut'>5: [73.19454286010809, 24.0139003560814]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.19454286010809</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.0139003560814</span></li></ul></li><li><label class='ee-shut'>6: [73.1942443392165, 24.0126807914708]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.1942443392165</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.0126807914708</span></li></ul></li><li><label class='ee-shut'>7: [73.1942341944796, 24.0126863557728]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.1942341944796</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.0126863557728</span></li></ul></li><li><label class='ee-shut'>8: [73.19653511275247, 24.01252023885471]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.19653511275247</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01252023885471</span></li></ul></li><li><label class='ee-shut'>9: [73.19648432210984, 24.01217871972386]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.19648432210984</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01217871972386</span></li></ul></li><li><label class='ee-shut'>10: [73.19764861281237, 24.01199930187962]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.19764861281237</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01199930187962</span></li></ul></li><li><label class='ee-shut'>11: [73.1981728693097, 24.01433254741455]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.1981728693097</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01433254741455</span></li></ul></li><li><label class='ee-shut'>12: [73.1986819814156, 24.01611200638915]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.1986819814156</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01611200638915</span></li></ul></li><li><label class='ee-shut'>13: [73.19959745133227, 24.01895266153662]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.19959745133227</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01895266153662</span></li></ul></li><li><label class='ee-shut'>14: [73.19791470947145, 24.01977640858627]<input type='checkbox' class='ee-toggle'></label><ul><li><span class='ee-k'>0:</span><span class='ee-v'>73.19791470947145</span></li><li><span class='ee-k'>1:</span><span class='ee-v'>24.01977640858627</span></li></ul></li></ul></li></ul></li></ul></li><li><label class='ee-shut'>properties: Object (0 properties)<input type='checkbox' class='ee-toggle'></label><ul></ul></li></ul></li></ul></li></ul></li></ul></div><script>function toggleHeader() {\n",
483
+ " const parent = this.parentElement;\n",
484
+ " parent.className = parent.className === \"ee-open\" ? \"ee-shut\" : \"ee-open\";\n",
485
+ "}\n",
486
+ "\n",
487
+ "for (let c of document.getElementsByClassName(\"ee-toggle\")) {\n",
488
+ " c.onclick = toggleHeader;\n",
489
+ "}</script></div>"
490
+ ],
491
+ "text/plain": [
492
+ "<ee.featurecollection.FeatureCollection at 0x7faa000c3160>"
493
+ ]
494
+ },
495
+ "execution_count": 6,
496
+ "metadata": {},
497
+ "output_type": "execute_result"
498
  }
499
  ],
500
  "source": [
 
507
  " return shape\n",
508
  "gdf['geometry'] = gdf['geometry'].apply(poly_3d_to_2d)\n",
509
  "gdf = gdf.to_crs(epsg=4326)\n",
510
+ "first_item = gdf.iloc[0].geometry.__geo_interface__\n",
511
+ "print(first_item)\n",
512
+ "print(type(first_item))\n",
513
+ "ee_geometry = ee.Geometry(first_item)\n",
514
+ "ee_feature_collection = ee.FeatureCollection(ee_geometry)\n",
515
+ "ee_feature_collection\n"
516
  ]
517
  },
518
  {
519
  "cell_type": "code",
520
+ "execution_count": 7,
521
  "metadata": {},
522
  "outputs": [
523
  {
 
558
  "name": "stdout",
559
  "output_type": "stream",
560
  "text": [
561
+ "['LANDSAT/LC08/C02/T1_TOA/LC08_148043_20230405', 'LANDSAT/LC08/C02/T1_TOA/LC08_148043_20230421', 'LANDSAT/LC08/C02/T1_TOA/LC08_148043_20230507', 'LANDSAT/LC08/C02/T1_TOA/LC08_148043_20230523', 'LANDSAT/LC08/C02/T1_TOA/LC08_148043_20230608', 'LANDSAT/LC08/C02/T1_TOA/LC08_148043_20230624', 'LANDSAT/LC08/C02/T1_TOA/LC08_148043_20230811', 'LANDSAT/LC08/C02/T1_TOA/LC08_148043_20230827', 'LANDSAT/LC08/C02/T1_TOA/LC08_148044_20230405', 'LANDSAT/LC08/C02/T1_TOA/LC08_148044_20230421', 'LANDSAT/LC08/C02/T1_TOA/LC08_148044_20230507', 'LANDSAT/LC08/C02/T1_TOA/LC08_148044_20230523', 'LANDSAT/LC08/C02/T1_TOA/LC08_148044_20230608', 'LANDSAT/LC08/C02/T1_TOA/LC08_148044_20230811', 'LANDSAT/LC08/C02/T1_TOA/LC08_148044_20230827']\n"
562
  ]
563
  }
564
  ],
565
  "source": [
566
+ "dataset = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA').filterBounds(ee_geometry).filterDate('2023-04', '2023-09')\n",
567
+ "# print image IDs\n",
568
+ "image_ids = dataset.aggregate_array('system:id').getInfo()\n",
569
+ "print(image_ids)\n",
570
+ "\n",
571
+ "# true_color_432 = dataset.select(['B4', 'B3', 'B2'])\n",
572
+ "# print(\"Number of images in the collection: \", true_color_432.size().getInfo())"
573
  ]
574
  },
575
  {
 
634
  },
635
  {
636
  "cell_type": "code",
637
+ "execution_count": 10,
638
  "metadata": {},
639
  "outputs": [
640
  {
 
675
  "name": "stdout",
676
  "output_type": "stream",
677
  "text": [
678
+ "Computing statistics ...\n"
 
 
 
 
679
  ]
680
+ },
681
+ {
682
+ "data": {
683
+ "text/plain": [
684
+ "{'type': 'FeatureCollection',\n",
685
+ " 'columns': {'mean': 'Float', 'system:index': 'String'},\n",
686
+ " 'features': [{'type': 'Feature',\n",
687
+ " 'geometry': {'type': 'Polygon',\n",
688
+ " 'coordinates': [[[73.19791470947145, 24.01977640858627],\n",
689
+ " [73.1951165609439, 24.01754094149261],\n",
690
+ " [73.1955205367043, 24.01738340683521],\n",
691
+ " [73.19480033400262, 24.01523619312771],\n",
692
+ " [73.19463695073262, 24.01440311871703],\n",
693
+ " [73.19454286010809, 24.0139003560814],\n",
694
+ " [73.1942443392165, 24.0126807914708],\n",
695
+ " [73.1942341944796, 24.0126863557728],\n",
696
+ " [73.19653511275247, 24.01252023885471],\n",
697
+ " [73.19648432210984, 24.01217871972386],\n",
698
+ " [73.19764861281237, 24.01199930187962],\n",
699
+ " [73.1981728693097, 24.01433254741455],\n",
700
+ " [73.1986819814156, 24.01611200638915],\n",
701
+ " [73.19959745133227, 24.01895266153662],\n",
702
+ " [73.19791470947145, 24.01977640858627]]]},\n",
703
+ " 'id': '0',\n",
704
+ " 'properties': {'mean': 0.7695880858277654}}]}"
705
+ ]
706
+ },
707
+ "execution_count": 10,
708
+ "metadata": {},
709
+ "output_type": "execute_result"
710
+ }
711
+ ],
712
+ "source": [
713
+ "geemap.zonal_stats(dataset.qualityMosaic(\"B4\").select([\"B4\"]), ee_feature_collection, statistics_type='mean', scale=10, return_fc=True).getInfo()"
714
+ ]
715
+ },
716
+ {
717
+ "cell_type": "code",
718
+ "execution_count": 61,
719
+ "metadata": {},
720
+ "outputs": [
721
+ {
722
+ "data": {
723
+ "text/html": [
724
+ "\n",
725
+ " <style>\n",
726
+ " .geemap-dark {\n",
727
+ " --jp-widgets-color: white;\n",
728
+ " --jp-widgets-label-color: white;\n",
729
+ " --jp-ui-font-color1: white;\n",
730
+ " --jp-layout-color2: #454545;\n",
731
+ " background-color: #383838;\n",
732
+ " }\n",
733
+ "\n",
734
+ " .geemap-dark .jupyter-button {\n",
735
+ " --jp-layout-color3: #383838;\n",
736
+ " }\n",
737
+ "\n",
738
+ " .geemap-colab {\n",
739
+ " background-color: var(--colab-primary-surface-color, white);\n",
740
+ " }\n",
741
+ "\n",
742
+ " .geemap-colab .jupyter-button {\n",
743
+ " --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
744
+ " }\n",
745
+ " </style>\n",
746
+ " "
747
+ ],
748
+ "text/plain": [
749
+ "<IPython.core.display.HTML object>"
750
+ ]
751
+ },
752
+ "metadata": {},
753
+ "output_type": "display_data"
754
+ },
755
+ {
756
+ "data": {
757
+ "text/plain": [
758
+ "[{'type': 'Feature',\n",
759
+ " 'geometry': {'type': 'Polygon',\n",
760
+ " 'coordinates': [[[73.19791470947145, 24.01977640858627],\n",
761
+ " [73.1951165609439, 24.01754094149261],\n",
762
+ " [73.1955205367043, 24.01738340683521],\n",
763
+ " [73.19480033400262, 24.01523619312771],\n",
764
+ " [73.19463695073262, 24.01440311871703],\n",
765
+ " [73.19454286010809, 24.0139003560814],\n",
766
+ " [73.1942443392165, 24.0126807914708],\n",
767
+ " [73.1942341944796, 24.0126863557728],\n",
768
+ " [73.19653511275247, 24.01252023885471],\n",
769
+ " [73.19648432210984, 24.01217871972386],\n",
770
+ " [73.19764861281237, 24.01199930187962],\n",
771
+ " [73.1981728693097, 24.01433254741455],\n",
772
+ " [73.1986819814156, 24.01611200638915],\n",
773
+ " [73.19959745133227, 24.01895266153662],\n",
774
+ " [73.19791470947145, 24.01977640858627]]]},\n",
775
+ " 'id': '0',\n",
776
+ " 'properties': {'mean': 0.7695880858277654}}]"
777
+ ]
778
+ },
779
+ "execution_count": 61,
780
+ "metadata": {},
781
+ "output_type": "execute_result"
782
  }
783
  ],
784
  "source": [
785
+ "features.getInfo()['features']"
786
  ]
787
  },
788
  {
zonal_stats.csv CHANGED
@@ -1,2 +1,2 @@
1
- mean,system:index,Description,Name
2
- 0.08817322105067514,0,<div><b>kelava irrigation he 25&nbsp;</b><br></div><div><b>Year 2022-23</b><br></div>,kelava 25 he
 
1
+ mean,system:index
2
+ 0.7695880858277654,0