Spaces:
Sleeping
Sleeping
keep sentinel. Apply changes
Browse files- app.py +228 -166
- sandbox.ipynb +532 -17
- 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 |
-
|
| 9 |
-
|
| 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[[
|
| 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(
|
| 80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
# normalize
|
| 82 |
-
cloud_mask_probability[f"{name}_cloud_proba"] =
|
| 83 |
-
|
|
|
|
|
|
|
| 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;">
|
| 100 |
""",
|
| 101 |
unsafe_allow_html=True,
|
| 102 |
)
|
| 103 |
|
| 104 |
# Input: Date and Cloud Cover
|
| 105 |
-
col = st.columns(
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
|
|
|
| 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 |
-
|
| 118 |
-
|
| 119 |
-
|
|
|
|
| 120 |
|
| 121 |
-
|
| 122 |
-
if
|
|
|
|
|
|
|
|
|
|
| 123 |
st.stop()
|
| 124 |
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
|
|
|
|
|
|
| 128 |
|
|
|
|
| 129 |
st.write("Select the satellite sources:")
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 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(
|
| 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
|
| 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
|
| 161 |
continue
|
| 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 |
-
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 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
fig
|
| 225 |
-
fig.update_yaxes(range=[0, 1])
|
| 226 |
st.plotly_chart(fig)
|
| 227 |
-
|
| 228 |
st.subheader("Visual Inspection")
|
| 229 |
-
|
|
|
|
|
|
|
| 230 |
cols = st.columns(2)
|
|
|
|
| 231 |
with cols[0]:
|
| 232 |
-
|
| 233 |
-
start_date_index = df[df.Date == start_date].index[0].item()
|
| 234 |
with cols[1]:
|
| 235 |
-
|
| 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 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
with col:
|
| 257 |
m = leaf_folium.Map()
|
| 258 |
-
m.add_tile_layer(
|
| 259 |
-
m.
|
| 260 |
-
|
| 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":
|
| 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":
|
| 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
|
| 102 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
]
|
| 104 |
},
|
| 105 |
{
|
| 106 |
"cell_type": "code",
|
| 107 |
-
"execution_count":
|
| 108 |
"metadata": {},
|
| 109 |
"outputs": [
|
| 110 |
{
|
|
@@ -145,14 +558,18 @@
|
|
| 145 |
"name": "stdout",
|
| 146 |
"output_type": "stream",
|
| 147 |
"text": [
|
| 148 |
-
"
|
| 149 |
]
|
| 150 |
}
|
| 151 |
],
|
| 152 |
"source": [
|
| 153 |
-
"dataset = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA').filterBounds(
|
| 154 |
-
"
|
| 155 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
]
|
| 157 |
},
|
| 158 |
{
|
|
@@ -217,7 +634,7 @@
|
|
| 217 |
},
|
| 218 |
{
|
| 219 |
"cell_type": "code",
|
| 220 |
-
"execution_count":
|
| 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
|
| 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
|
| 2 |
-
0.
|
|
|
|
| 1 |
+
mean,system:index
|
| 2 |
+
0.7695880858277654,0
|