increase index
Browse files
app.py
CHANGED
|
@@ -277,12 +277,16 @@ def get_dem_slope_maps(ee_geometry, map_bounds, wayback_url, wayback_title, zoom
|
|
| 277 |
|
| 278 |
return dem_map_html, slope_map_html
|
| 279 |
|
| 280 |
-
def add_indices(image, nir_band, red_band, blue_band, green_band, evi_vars):
|
| 281 |
"""Calculates and adds multiple vegetation indices to an Earth Engine image."""
|
| 282 |
nir = image.select(nir_band).divide(10000)
|
| 283 |
red = image.select(red_band).divide(10000)
|
| 284 |
blue = image.select(blue_band).divide(10000)
|
| 285 |
green = image.select(green_band).divide(10000)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 286 |
ndvi = image.normalizedDifference([nir_band, red_band]).rename('NDVI')
|
| 287 |
evi = image.expression(
|
| 288 |
'G * ((NIR - RED) / (NIR + C1 * RED - C2 * BLUE + L))', {
|
|
@@ -312,7 +316,21 @@ def add_indices(image, nir_band, red_band, blue_band, green_band, evi_vars):
|
|
| 312 |
'0.5 * (NIR - RED) / (NIR + 6 * RED - 8.25 * BLUE - 0.01)', {
|
| 313 |
'NIR': nir, 'RED': red, 'BLUE': blue
|
| 314 |
}).rename('GujVDI')
|
| 315 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 316 |
|
| 317 |
|
| 318 |
# --- Gradio App Logic ---
|
|
@@ -380,49 +398,6 @@ def process_and_display(file_obj, url_str, buffer_m, progress=gr.Progress()):
|
|
| 380 |
progress(1, desc="Done!")
|
| 381 |
return m._repr_html_(), None, stats_df, dem_html, slope_html, geometry_json, buffer_geometry_json
|
| 382 |
|
| 383 |
-
|
| 384 |
-
@app.get("/api/geometry1")
|
| 385 |
-
def calculate_geometry_metrics(file_url: str):
|
| 386 |
-
"""
|
| 387 |
-
Accepts a URL to a KML/GeoJSON file, calculates the area and
|
| 388 |
-
perimeter of the first valid polygon, and returns the results.
|
| 389 |
-
"""
|
| 390 |
-
try:
|
| 391 |
-
|
| 392 |
-
decoded_url = unquote(file_url)
|
| 393 |
-
input_gdf = get_gdf_from_url(decoded_url)
|
| 394 |
-
if input_gdf is None or input_gdf.empty:
|
| 395 |
-
raise ValueError("Could not read geometry from the provided URL.")
|
| 396 |
-
input_gdf = preprocess_gdf(input_gdf)
|
| 397 |
-
geometry_gdf = next((input_gdf.iloc[[i]] for i in range(len(input_gdf)) if is_valid_polygon(input_gdf.iloc[[i]])), None)
|
| 398 |
-
|
| 399 |
-
if geometry_gdf is None:
|
| 400 |
-
raise ValueError("No valid polygon found in the provided file.")
|
| 401 |
-
projected_gdf = to_best_crs(geometry_gdf)
|
| 402 |
-
|
| 403 |
-
# Calculate area (in hectares) and perimeter (in meters)
|
| 404 |
-
area_hectares = projected_gdf.area.item() / 10000
|
| 405 |
-
perimeter_meters = projected_gdf.length.item()
|
| 406 |
-
|
| 407 |
-
# reproject to WGS84 (EPSG:4326)
|
| 408 |
-
centroid_gdf = projected_gdf.to_crs(epsg=4326)
|
| 409 |
-
centroid_point = centroid_gdf.centroid.item()
|
| 410 |
-
|
| 411 |
-
return {
|
| 412 |
-
"area_hectares": round(area_hectares, 4),
|
| 413 |
-
"perimeter_meters": round(perimeter_meters, 4),
|
| 414 |
-
"latitude": round(centroid_point.y, 4),
|
| 415 |
-
"longitude": round(centroid_point.x, 4)
|
| 416 |
-
}
|
| 417 |
-
|
| 418 |
-
except ValueError as e:
|
| 419 |
-
# Handle specific errors like bad URLs, no polygons, etc. with a 400 Bad Request
|
| 420 |
-
raise HTTPException(status_code=400, detail=str(e))
|
| 421 |
-
except Exception as e:
|
| 422 |
-
# Handle any other unexpected errors with a 500 Internal Server Error
|
| 423 |
-
print(f"An unexpected error occurred in /api/geometry: {e}")
|
| 424 |
-
raise HTTPException(status_code=500, detail="An unexpected server error occurred.")
|
| 425 |
-
|
| 426 |
@app.get("/api/geometry")
|
| 427 |
def calculate_geometry_metrics(file_url: str):
|
| 428 |
"""
|
|
@@ -494,10 +469,10 @@ def calculate_indices(
|
|
| 494 |
collection = (
|
| 495 |
ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
|
| 496 |
.select(
|
| 497 |
-
["B2", "B3", "B4", "B8", "MSK_CLDPRB"],
|
| 498 |
-
["Blue", "Green", "Red", "NIR", "MSK_CLDPRB"]
|
| 499 |
)
|
| 500 |
-
.map(lambda img: add_indices(img, 'NIR', 'Red', 'Blue', 'Green', evi_vars))
|
| 501 |
)
|
| 502 |
|
| 503 |
result_rows = []
|
|
@@ -614,8 +589,11 @@ def generate_comparison_maps(geometry_json, selected_index, selected_years, evi_
|
|
| 614 |
ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
|
| 615 |
.filterDate(start_date, end_date)
|
| 616 |
.filterBounds(ee_geometry)
|
| 617 |
-
.select(
|
| 618 |
-
|
|
|
|
|
|
|
|
|
|
| 619 |
)
|
| 620 |
|
| 621 |
if collection.size().getInfo() == 0:
|
|
@@ -721,7 +699,7 @@ with gr.Blocks(theme=theme, title="Kamlan: KML Analyzer") as demo:
|
|
| 721 |
|
| 722 |
with gr.Accordion("Advanced Settings", open=False):
|
| 723 |
gr.Markdown("### Select Vegetation Indices")
|
| 724 |
-
all_veg_indices = ["GujVDI", "NDVI", "EVI", "EVI2", "RandomForest", "CI"]
|
| 725 |
veg_indices_checkboxes = gr.CheckboxGroup(all_veg_indices, label="Indices", value=["NDVI"])
|
| 726 |
|
| 727 |
gr.Markdown("### EVI/EVI2 Parameters")
|
|
@@ -873,8 +851,11 @@ def compute_index_histogram(file_url: str, index_name: str, start_date: str, end
|
|
| 873 |
collection = (
|
| 874 |
ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
|
| 875 |
.filterDate(start_date, end_date)
|
| 876 |
-
.select(
|
| 877 |
-
|
|
|
|
|
|
|
|
|
|
| 878 |
.filterBounds(ee_geometry)
|
| 879 |
)
|
| 880 |
|
|
@@ -921,7 +902,7 @@ def compute_index_histogram(file_url: str, index_name: str, start_date: str, end
|
|
| 921 |
return Response(content=final_string, media_type="text/csv")
|
| 922 |
|
| 923 |
# Register endpoints for multiple indices with date range
|
| 924 |
-
for idx in ["NDVI", "EVI", "EVI2", "RandomForest", "CI", "GujVDI"]:
|
| 925 |
endpoint_path = f"/api/{idx}"
|
| 926 |
|
| 927 |
async def index_hist_endpoint(file_url: str, start_date: str, end_date: str, index_name=idx):
|
|
|
|
| 277 |
|
| 278 |
return dem_map_html, slope_map_html
|
| 279 |
|
| 280 |
+
def add_indices(image, nir_band, red_band, blue_band, green_band, swir_band, swir2_band, evi_vars):
|
| 281 |
"""Calculates and adds multiple vegetation indices to an Earth Engine image."""
|
| 282 |
nir = image.select(nir_band).divide(10000)
|
| 283 |
red = image.select(red_band).divide(10000)
|
| 284 |
blue = image.select(blue_band).divide(10000)
|
| 285 |
green = image.select(green_band).divide(10000)
|
| 286 |
+
swir = image.select(swir_band).divide(10000)
|
| 287 |
+
swir2 = image.select(swir2_band).divide(10000)
|
| 288 |
+
|
| 289 |
+
# Previously existing indices
|
| 290 |
ndvi = image.normalizedDifference([nir_band, red_band]).rename('NDVI')
|
| 291 |
evi = image.expression(
|
| 292 |
'G * ((NIR - RED) / (NIR + C1 * RED - C2 * BLUE + L))', {
|
|
|
|
| 316 |
'0.5 * (NIR - RED) / (NIR + 6 * RED - 8.25 * BLUE - 0.01)', {
|
| 317 |
'NIR': nir, 'RED': red, 'BLUE': blue
|
| 318 |
}).rename('GujVDI')
|
| 319 |
+
mndwi = image.normalizedDifference([green_band, swir_band]).rename('MNDWI')
|
| 320 |
+
|
| 321 |
+
# Newly added indices
|
| 322 |
+
savi = image.expression('(1 + L) * (NIR - RED) / (NIR + RED + L)', {
|
| 323 |
+
'NIR': nir, 'RED': red, 'L': 0.5
|
| 324 |
+
}).rename('SAVI')
|
| 325 |
+
mvi = image.expression('(NIR - (GREEN + SWIR)) / (NIR + (GREEN + SWIR))', {
|
| 326 |
+
'NIR': nir, 'GREEN': green, 'SWIR': swir
|
| 327 |
+
}).rename('MVI')
|
| 328 |
+
nbr = image.normalizedDifference([nir_band, swir2_band]).rename('NBR')
|
| 329 |
+
gci = image.expression('(NIR - GREEN) / GREEN', {
|
| 330 |
+
'NIR': nir, 'GREEN': green
|
| 331 |
+
}).rename('GCI')
|
| 332 |
+
|
| 333 |
+
return image.addBands([ndvi, evi, evi2, rf, ci, gujvdi, mndwi, savi, mvi, nbr, gci])
|
| 334 |
|
| 335 |
|
| 336 |
# --- Gradio App Logic ---
|
|
|
|
| 398 |
progress(1, desc="Done!")
|
| 399 |
return m._repr_html_(), None, stats_df, dem_html, slope_html, geometry_json, buffer_geometry_json
|
| 400 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 401 |
@app.get("/api/geometry")
|
| 402 |
def calculate_geometry_metrics(file_url: str):
|
| 403 |
"""
|
|
|
|
| 469 |
collection = (
|
| 470 |
ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
|
| 471 |
.select(
|
| 472 |
+
["B2", "B3", "B4", "B8", "B11", "B12", "MSK_CLDPRB"],
|
| 473 |
+
["Blue", "Green", "Red", "NIR", "SWIR", "SWIR2", "MSK_CLDPRB"]
|
| 474 |
)
|
| 475 |
+
.map(lambda img: add_indices(img, 'NIR', 'Red', 'Blue', 'Green', 'SWIR', 'SWIR2', evi_vars))
|
| 476 |
)
|
| 477 |
|
| 478 |
result_rows = []
|
|
|
|
| 589 |
ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
|
| 590 |
.filterDate(start_date, end_date)
|
| 591 |
.filterBounds(ee_geometry)
|
| 592 |
+
.select(
|
| 593 |
+
["B2", "B3", "B4", "B8", "B11", "B12", "MSK_CLDPRB"],
|
| 594 |
+
["Blue", "Green", "Red", "NIR", "SWIR", "SWIR2", "MSK_CLDPRB"]
|
| 595 |
+
)
|
| 596 |
+
.map(lambda img: add_indices(img, 'NIR', 'Red', 'Blue', 'Green', 'SWIR', 'SWIR2', evi_vars))
|
| 597 |
)
|
| 598 |
|
| 599 |
if collection.size().getInfo() == 0:
|
|
|
|
| 699 |
|
| 700 |
with gr.Accordion("Advanced Settings", open=False):
|
| 701 |
gr.Markdown("### Select Vegetation Indices")
|
| 702 |
+
all_veg_indices = ["GujVDI", "NDVI", "EVI", "EVI2", "RandomForest", "CI", "MNDWI", "SAVI", "MVI", "NBR", "GCI"]
|
| 703 |
veg_indices_checkboxes = gr.CheckboxGroup(all_veg_indices, label="Indices", value=["NDVI"])
|
| 704 |
|
| 705 |
gr.Markdown("### EVI/EVI2 Parameters")
|
|
|
|
| 851 |
collection = (
|
| 852 |
ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
|
| 853 |
.filterDate(start_date, end_date)
|
| 854 |
+
.select(
|
| 855 |
+
["B2", "B3", "B4", "B8", "B11", "B12", "MSK_CLDPRB"],
|
| 856 |
+
["Blue", "Green", "Red", "NIR", "SWIR", "SWIR2", "MSK_CLDPRB"]
|
| 857 |
+
)
|
| 858 |
+
.map(lambda img: add_indices(img, 'NIR', 'Red', 'Blue', 'Green', 'SWIR', 'SWIR2', evi_vars))
|
| 859 |
.filterBounds(ee_geometry)
|
| 860 |
)
|
| 861 |
|
|
|
|
| 902 |
return Response(content=final_string, media_type="text/csv")
|
| 903 |
|
| 904 |
# Register endpoints for multiple indices with date range
|
| 905 |
+
for idx in ["NDVI", "EVI", "EVI2", "RandomForest", "CI", "GujVDI", "MNDWI", "SAVI", "MVI", "NBR", "GCI"]:
|
| 906 |
endpoint_path = f"/api/{idx}"
|
| 907 |
|
| 908 |
async def index_hist_endpoint(file_url: str, start_date: str, end_date: str, index_name=idx):
|