UjjwalKGupta commited on
Commit
f6b20a0
·
verified ·
1 Parent(s): 62b5810

Add legend and histogram

Browse files
Files changed (1) hide show
  1. app.py +40 -39
app.py CHANGED
@@ -467,7 +467,7 @@ def get_histogram(index_name, image, geometry, bins):
467
  return np.array([0] * (len(bins) - 1)), bins
468
 
469
  def generate_comparison_maps(geometry_json, selected_index, selected_years, evi_vars, date_start_str, date_end_str, progress=gr.Progress()):
470
- """Generates side-by-side maps for a selected index and two selected years with a classified legend."""
471
  if not geometry_json or not selected_index or not selected_years:
472
  return "Please process a file and select an index and years first.", "", ""
473
  if len(selected_years) != 2:
@@ -508,16 +508,12 @@ def generate_comparison_maps(geometry_json, selected_index, selected_years, evi_
508
  print(f"Could not find a suitable Wayback basemap for {year}: {e}")
509
  wayback_url = None
510
  wayback_title = "Default Satellite"
511
- # --- End Wayback Logic ---
512
-
513
  collection = (
514
  ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
515
  .filterDate(start_date, end_date)
516
  .filterBounds(ee_geometry)
517
- .select(
518
- ["B2", "B3", "B4", "B8"],
519
- ["Blue", "Green", "Red", "NIR"]
520
- )
521
  .map(lambda img: add_indices(img, 'NIR', 'Red', 'Blue', 'Green', evi_vars))
522
  )
523
 
@@ -526,59 +522,64 @@ def generate_comparison_maps(geometry_json, selected_index, selected_years, evi_
526
  continue
527
 
528
  mosaic = collection.qualityMosaic(selected_index)
529
-
530
- # Create the base map
531
  m = gee_folium.Map(zoom_start=14)
532
  if wayback_url:
533
  m.add_tile_layer(wayback_url, name=wayback_title, attribution="Esri")
534
  else:
535
  m.add_basemap("SATELLITE")
536
 
537
- # --- START: New Legend and Layer Logic ---
538
  if selected_index in ["NDVI", "RandomForest", "GujVDI", "CI", "EVI", "EVI2"]:
539
- # Define bins for classification
540
  bins = [0, 0.2, 0.4, 0.6, 0.8, 1]
541
- histogram, bin_edges = get_histogram(selected_index, mosaic.select(selected_index), ee_geometry, bins)
542
 
543
  total_pix = np.sum(histogram)
544
- # Format histogram values as percentages, handle division by zero
545
  if total_pix > 0:
546
  formatted_histogram = [f"{h*100/total_pix:.2f}" for h in histogram]
547
- else:
548
- formatted_histogram = ["0.00"] * len(histogram)
549
-
550
- # Add the classified legend to the map
551
- m.add_legend(
552
- title=f"{selected_index} Classification ({year})",
553
- legend_dict={
554
- "0-0.2: Open/Sparse Vegetation ({}%)".format(formatted_histogram[0]): "#FF0000",
555
- "0.2-0.4: Low Vegetation ({}%)".format(formatted_histogram[1]): "#FFFF00",
556
- "0.4-0.6: Moderate Vegetation ({}%)".format(formatted_histogram[2]): "#FFA500",
557
- "0.6-0.8: Dense Vegetation ({}%)".format(formatted_histogram[3]): "#00FE00",
558
- "0.8-1: Very Dense Vegetation ({}%)".format(formatted_histogram[4]): "#00A400",
559
- },
560
- position="bottomright",
561
- draggable=False,
562
- )
563
 
564
  # Define visualization parameters for the classified layer
565
  ind_vis_params = {
566
- "min": 0,
567
- "max": 1,
568
  "palette": ["#FF0000", "#FFFF00", "#FFA500", "#00FE00", "#00A400"],
569
  }
570
- # Add the classified raster layer to the map
571
  m.addLayer(mosaic.select(selected_index).clip(ee_geometry), ind_vis_params, f"{selected_index} Classified Layer ({year})")
572
-
573
- else: # Fallback for indices without a classified legend (original behavior)
574
- vis_params = {
575
- "min": 0.0, "max": 1.0,
576
- "palette": ['FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901', '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01', '012E01', '011D01', '011301']
 
 
577
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
578
  clipped_image = mosaic.select(selected_index).clip(ee_geometry)
579
  m.addLayer(clipped_image, vis_params, f"{selected_index} {year}")
580
  m.add_colorbar(vis_params=vis_params, label=f"{selected_index} Value")
581
- # --- END: New Legend and Layer Logic ---
582
 
583
  folium.GeoJson(geometry_gdf, name="Geometry", style_function=lambda x: {"color": "yellow", "fillOpacity": 0, "weight": 2.5}).add_to(m)
584
  m.fit_bounds(map_bounds, padding=(10, 10))
@@ -590,7 +591,7 @@ def generate_comparison_maps(geometry_json, selected_index, selected_years, evi_
590
 
591
  return f"Comparison generated for {selected_years[0]} and {selected_years[1]}.", maps_html[0], maps_html[1]
592
 
593
- # --- Gradio Interface (unchanged) ---
594
  theme = gr.themes.Soft(primary_hue="teal", secondary_hue="orange").set(
595
  background_fill_primary="white"
596
  )
 
467
  return np.array([0] * (len(bins) - 1)), bins
468
 
469
  def generate_comparison_maps(geometry_json, selected_index, selected_years, evi_vars, date_start_str, date_end_str, progress=gr.Progress()):
470
+ """Generates side-by-side maps for a selected index and two selected years with a custom HTML legend."""
471
  if not geometry_json or not selected_index or not selected_years:
472
  return "Please process a file and select an index and years first.", "", ""
473
  if len(selected_years) != 2:
 
508
  print(f"Could not find a suitable Wayback basemap for {year}: {e}")
509
  wayback_url = None
510
  wayback_title = "Default Satellite"
511
+
 
512
  collection = (
513
  ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
514
  .filterDate(start_date, end_date)
515
  .filterBounds(ee_geometry)
516
+ .select(["B2", "B3", "B4", "B8"], ["Blue", "Green", "Red", "NIR"])
 
 
 
517
  .map(lambda img: add_indices(img, 'NIR', 'Red', 'Blue', 'Green', evi_vars))
518
  )
519
 
 
522
  continue
523
 
524
  mosaic = collection.qualityMosaic(selected_index)
 
 
525
  m = gee_folium.Map(zoom_start=14)
526
  if wayback_url:
527
  m.add_tile_layer(wayback_url, name=wayback_title, attribution="Esri")
528
  else:
529
  m.add_basemap("SATELLITE")
530
 
531
+ # --- START: MODIFIED LEGEND AND LAYER LOGIC ---
532
  if selected_index in ["NDVI", "RandomForest", "GujVDI", "CI", "EVI", "EVI2"]:
 
533
  bins = [0, 0.2, 0.4, 0.6, 0.8, 1]
534
+ histogram, _ = get_histogram(selected_index, mosaic.select(selected_index), ee_geometry, bins)
535
 
536
  total_pix = np.sum(histogram)
537
+ formatted_histogram = ["0.00"] * len(histogram)
538
  if total_pix > 0:
539
  formatted_histogram = [f"{h*100/total_pix:.2f}" for h in histogram]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
 
541
  # Define visualization parameters for the classified layer
542
  ind_vis_params = {
543
+ "min": 0, "max": 1,
 
544
  "palette": ["#FF0000", "#FFFF00", "#FFA500", "#00FE00", "#00A400"],
545
  }
 
546
  m.addLayer(mosaic.select(selected_index).clip(ee_geometry), ind_vis_params, f"{selected_index} Classified Layer ({year})")
547
+
548
+ legend_items = {
549
+ f"0-0.2: Open/Sparse Vegetation ({formatted_histogram[0]}%)": "#FF0000",
550
+ f"0.2-0.4: Low Vegetation ({formatted_histogram[1]}%)": "#FFFF00",
551
+ f"0.4-0.6: Moderate Vegetation ({formatted_histogram[2]}%)": "#FFA500",
552
+ f"0.6-0.8: Dense Vegetation ({formatted_histogram[3]}%)": "#00FE00",
553
+ f"0.8-1: Very Dense Vegetation ({formatted_histogram[4]}%)": "#00A400",
554
  }
555
+
556
+ legend_html = f'''
557
+ <div style="
558
+ position: fixed;
559
+ bottom: 20px;
560
+ right: 10px;
561
+ z-index:9999;
562
+ font-size:14px;
563
+ background-color: rgba(255, 255, 255, 0.85);
564
+ border:2px solid grey;
565
+ padding: 10px;
566
+ border-radius: 6px;
567
+ ">
568
+ <b>{selected_index} Classification ({year})</b>
569
+ <ul style="list-style-type: none; padding-left: 0; margin: 5px 0 0 0;">
570
+ '''
571
+ for text, color in legend_items.items():
572
+ legend_html += f'<li><i style="background:{color}; width:20px; height:15px; display:inline-block; margin-right:5px; vertical-align:middle; border: 1px solid black;"></i> {text}</li>'
573
+ legend_html += "</ul></div>"
574
+
575
+ # Add the raw HTML to the map
576
+ m.get_root().html.add_child(folium.Element(legend_html))
577
+
578
+ else: # Fallback for indices without a color bar
579
+ vis_params = {"min": 0.0, "max": 1.0, "palette": ['FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901', '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01', '012E01', '011D01', '011301']}
580
  clipped_image = mosaic.select(selected_index).clip(ee_geometry)
581
  m.addLayer(clipped_image, vis_params, f"{selected_index} {year}")
582
  m.add_colorbar(vis_params=vis_params, label=f"{selected_index} Value")
 
583
 
584
  folium.GeoJson(geometry_gdf, name="Geometry", style_function=lambda x: {"color": "yellow", "fillOpacity": 0, "weight": 2.5}).add_to(m)
585
  m.fit_bounds(map_bounds, padding=(10, 10))
 
591
 
592
  return f"Comparison generated for {selected_years[0]} and {selected_years[1]}.", maps_html[0], maps_html[1]
593
 
594
+ # --- Gradio Interface ---
595
  theme = gr.themes.Soft(primary_hue="teal", secondary_hue="orange").set(
596
  background_fill_primary="white"
597
  )