oberbics commited on
Commit
8bf8409
·
verified ·
1 Parent(s): b1dd40e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +229 -104
app.py CHANGED
@@ -347,120 +347,124 @@ def extract_info(template, text):
347
  print(f"Error in extract_info: {e}\n{trace}")
348
  return f"❌ Fehler: {str(e)}", "{}"
349
  @spaces.GPU
350
- @spaces.GPU
351
- def create_map(df, location_col):
352
- # Start a simple log to track execution
353
- with open("map_debug.log", "w") as log:
354
- log.write(f"Starting map creation at {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
355
-
356
- m = folium.Map(
357
- location=[20, 0],
358
- zoom_start=2,
359
- control_scale=True
360
- )
361
-
362
- folium.TileLayer(
363
- tiles=MAP_TILES["GreenMap"]["url"],
364
- attr=MAP_TILES["GreenMap"]["attr"],
365
- name="GreenMap",
366
- overlay=False,
367
- control=False
368
- ).add_to(m)
369
 
370
- Fullscreen().add_to(m)
371
- MeasureControl(position='topright', primary_length_unit='kilometers').add_to(m)
372
 
 
373
  geocoder = SafeGeocoder()
374
- coords = []
375
- marker_cluster = MarkerCluster(name="Locations").add_to(m)
376
  processed_count = 0
 
 
 
377
 
378
- with open("map_debug.log", "a") as log:
379
- log.write(f"Processing {len(df)} rows from dataframe\n")
380
-
381
  for idx, row in df.iterrows():
382
  if pd.isna(row[location_col]):
383
  continue
384
 
385
  location = str(row[location_col]).strip()
386
 
387
- # Log the location being processed
388
- with open("map_debug.log", "a") as log:
389
- log.write(f"Processing location: {location}\n")
390
-
391
  additional_info = ""
392
  for col in df.columns:
393
  if col != location_col and not pd.isna(row[col]):
394
  additional_info += f"<br><b>{col}:</b> {row[col]}"
395
 
 
396
  try:
397
  locations = [loc.strip() for loc in location.split(',') if loc.strip()]
398
  if not locations:
399
  locations = [location]
400
  except Exception as e:
401
- with open("map_debug.log", "a") as log:
402
- log.write(f"Error splitting location '{location}': {str(e)}\n")
403
  locations = [location]
404
-
405
- # Log the parsed locations
406
- with open("map_debug.log", "a") as log:
407
- log.write(f"Split into locations: {locations}\n")
408
 
 
409
  for loc in locations:
410
  try:
411
- # Log the current location
412
- with open("map_debug.log", "a") as log:
413
- log.write(f"Getting coordinates for: {loc}\n")
414
-
415
  point = geocoder.get_coords(loc)
416
 
417
  if point:
418
- # Log the found coordinates
419
- with open("map_debug.log", "a") as log:
420
- log.write(f"Found coordinates for {loc}: {point}\n")
421
-
422
- # Create popup HTML - this is the part that was disappearing
423
- popup_content = f"""
424
- <div style="min-width: 200px; max-width: 300px">
425
- <h4 style="font-family: 'Source Sans Pro', sans-serif; margin-bottom: 5px;">{loc}</h4>
426
- <div style="font-family: 'Source Sans Pro', sans-serif; font-size: 14px;">
427
- {additional_info}
428
- </div>
429
- </div>
430
- """
431
 
432
- # Log popup creation
433
- with open("map_debug.log", "a") as log:
434
- log.write(f"Created popup for {loc}\n")
435
 
436
- # Add marker with popup
437
- folium.Marker(
438
- location=point,
439
- popup=folium.Popup(popup_content, max_width=300),
440
- tooltip=loc,
441
- icon=folium.Icon(color="blue", icon="info-sign")
442
- ).add_to(marker_cluster)
443
-
444
- # Log marker addition
445
- with open("map_debug.log", "a") as log:
446
- log.write(f"Added marker for {loc}\n")
447
-
448
- coords.append(point)
449
  processed_count += 1
450
- else:
451
- # Log geocoding failure
452
- with open("map_debug.log", "a") as log:
453
- log.write(f"No coordinates found for {loc}\n")
454
  except Exception as e:
455
- # Log any errors in processing this location
456
- with open("map_debug.log", "a") as log:
457
- log.write(f"Error processing {loc}: {str(e)}\n")
458
- log.write(traceback.format_exc() + "\n")
459
-
460
- # Fit map bounds if we have coordinates
461
- if coords:
462
- m.fit_bounds(coords)
463
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
464
  # Custom CSS for map
465
  custom_css = """
466
  <style>
@@ -801,6 +805,124 @@ Die Katastrophe in <span style="background-color: #a8e6cf; font-weight: bold; pa
801
  """)
802
 
803
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
804
  with gr.TabItem("📍 Visualisierung von strukturierten Daten"):
805
  gr.HTML("""
806
  <div class="info-box">
@@ -834,37 +956,39 @@ Die Katastrophe in <span style="background-color: #a8e6cf; font-weight: bold; pa
834
  )
835
 
836
  with gr.Column():
837
- map_output = gr.HTML(
838
- label="Interaktive Karte",
839
- value="""
840
- <div style="text-align:center; height:20vh; width:100%; display:flex; align-items:center; justify-content:center;
841
- background-color:#f5f5f5; border:1px solid #e0e0e0; border-radius:8px;">
842
- <div>
843
- <img src="https://cdn-icons-png.flaticon.com/512/854/854878.png" width="100">
844
- <p style="margin-top:20px; color:#666;">Your map will appear here after processing</p>
845
- </div>
846
- </div>
847
- """,
848
- elem_id="map-container"
849
  )
850
-
851
 
 
852
  def process_and_map(file, column):
853
  if file is None:
854
  return None, "Hier bitte die Excel-Tabelle hochladen", None
855
 
856
  try:
857
- map_html, stats, processed_path = process_excel(file, column)
858
-
859
- if map_html and processed_path:
860
- responsive_html = f"""
861
- <div style="width:100%; height:20vh; margin:0; padding:0; border:1px solid #e0e0e0; border-radius:8px; overflow:hidden;">
862
- {map_html}
863
- </div>
864
- """
865
- return responsive_html, stats, processed_path
866
  else:
867
- return None, stats, None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
868
  except Exception as e:
869
  import traceback
870
  trace = traceback.format_exc()
@@ -876,6 +1000,7 @@ Die Katastrophe in <span style="background-color: #a8e6cf; font-weight: bold; pa
876
  inputs=[excel_file, places_column],
877
  outputs=[map_output, stats_output, processed_file]
878
  )
 
879
 
880
  gr.HTML("""
881
  <div style="text-align: center; margin-top: 2rem; padding-top: 1rem; border-top: 1px solid #eee; font-size: 0.9rem; color: #666;">
 
347
  print(f"Error in extract_info: {e}\n{trace}")
348
  return f"❌ Fehler: {str(e)}", "{}"
349
  @spaces.GPU
350
+
351
+ # Instead of using folium directly with Gradio's HTML component,
352
+ # try this alternative approach using Plotly for maps
353
+
354
+ def create_map_plotly(df, location_col):
355
+ """
356
+ Creates an interactive map using Plotly instead of Folium
357
+ which should be more stable in Gradio applications
358
+ """
359
+ import plotly.graph_objects as go
360
+ import pandas as pd
 
 
 
 
 
 
 
 
361
 
362
+ # Track processing for debugging
363
+ print(f"Processing {len(df)} rows with location column: {location_col}")
364
 
365
+ # Initialize geocoder and tracking variables
366
  geocoder = SafeGeocoder()
 
 
367
  processed_count = 0
368
+ all_lats = []
369
+ all_lons = []
370
+ hover_texts = []
371
 
372
+ # Process each row
 
 
373
  for idx, row in df.iterrows():
374
  if pd.isna(row[location_col]):
375
  continue
376
 
377
  location = str(row[location_col]).strip()
378
 
379
+ # Build additional info for hover text
 
 
 
380
  additional_info = ""
381
  for col in df.columns:
382
  if col != location_col and not pd.isna(row[col]):
383
  additional_info += f"<br><b>{col}:</b> {row[col]}"
384
 
385
+ # Split location if it contains multiple comma-separated places
386
  try:
387
  locations = [loc.strip() for loc in location.split(',') if loc.strip()]
388
  if not locations:
389
  locations = [location]
390
  except Exception as e:
391
+ print(f"Error splitting location '{location}': {str(e)}")
 
392
  locations = [location]
 
 
 
 
393
 
394
+ # Process each individual location
395
  for loc in locations:
396
  try:
397
+ # Get coordinates
 
 
 
398
  point = geocoder.get_coords(loc)
399
 
400
  if point:
401
+ lat, lon = point
402
+ all_lats.append(lat)
403
+ all_lons.append(lon)
 
 
 
 
 
 
 
 
 
 
404
 
405
+ # Create hover text with location name and info
406
+ hover_text = f"<b>{loc}</b>{additional_info}"
407
+ hover_texts.append(hover_text)
408
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
  processed_count += 1
 
 
 
 
410
  except Exception as e:
411
+ print(f"Error processing location {loc}: {str(e)}")
 
 
 
 
 
 
 
412
 
413
+ # Create Plotly map
414
+ if len(all_lats) > 0:
415
+ fig = go.Figure()
416
+
417
+ # Add scatter mapbox points
418
+ fig.add_trace(go.Scattermapbox(
419
+ lat=all_lats,
420
+ lon=all_lons,
421
+ mode='markers',
422
+ marker=go.scattermapbox.Marker(
423
+ size=10,
424
+ color='blue'
425
+ ),
426
+ text=hover_texts,
427
+ hoverinfo="text"
428
+ ))
429
+
430
+ # Configure map layout
431
+ fig.update_layout(
432
+ mapbox_style="open-street-map",
433
+ mapbox=dict(
434
+ center={"lat": sum(all_lats)/len(all_lats) if all_lats else 20,
435
+ "lon": sum(all_lons)/len(all_lons) if all_lons else 0},
436
+ zoom=3
437
+ ),
438
+ margin={"r":0,"t":0,"l":0,"b":0},
439
+ height=600
440
+ )
441
+
442
+ return fig, processed_count
443
+ else:
444
+ # Create empty figure if no coordinates found
445
+ fig = go.Figure()
446
+ fig.update_layout(
447
+ mapbox_style="open-street-map",
448
+ mapbox=dict(
449
+ center={"lat": 20, "lon": 0},
450
+ zoom=2
451
+ ),
452
+ margin={"r":0,"t":0,"l":0,"b":0},
453
+ height=600,
454
+ annotations=[
455
+ dict(
456
+ text="No locations found to display",
457
+ showarrow=False,
458
+ xref="paper",
459
+ yref="paper",
460
+ x=0.5,
461
+ y=0.5
462
+ )
463
+ ]
464
+ )
465
+ return fig, 0
466
+
467
+
468
  # Custom CSS for map
469
  custom_css = """
470
  <style>
 
805
  """)
806
 
807
 
808
+ # Instead of using folium directly with Gradio's HTML component,
809
+ # try this alternative approach using Plotly for maps
810
+
811
+ def create_map_plotly(df, location_col):
812
+ """
813
+ Creates an interactive map using Plotly instead of Folium
814
+ which should be more stable in Gradio applications
815
+ """
816
+ import plotly.graph_objects as go
817
+ import pandas as pd
818
+
819
+ # Track processing for debugging
820
+ print(f"Processing {len(df)} rows with location column: {location_col}")
821
+
822
+ # Initialize geocoder and tracking variables
823
+ geocoder = SafeGeocoder()
824
+ processed_count = 0
825
+ all_lats = []
826
+ all_lons = []
827
+ hover_texts = []
828
+
829
+ # Process each row
830
+ for idx, row in df.iterrows():
831
+ if pd.isna(row[location_col]):
832
+ continue
833
+
834
+ location = str(row[location_col]).strip()
835
+
836
+ # Build additional info for hover text
837
+ additional_info = ""
838
+ for col in df.columns:
839
+ if col != location_col and not pd.isna(row[col]):
840
+ additional_info += f"<br><b>{col}:</b> {row[col]}"
841
+
842
+ # Split location if it contains multiple comma-separated places
843
+ try:
844
+ locations = [loc.strip() for loc in location.split(',') if loc.strip()]
845
+ if not locations:
846
+ locations = [location]
847
+ except Exception as e:
848
+ print(f"Error splitting location '{location}': {str(e)}")
849
+ locations = [location]
850
+
851
+ # Process each individual location
852
+ for loc in locations:
853
+ try:
854
+ # Get coordinates
855
+ point = geocoder.get_coords(loc)
856
+
857
+ if point:
858
+ lat, lon = point
859
+ all_lats.append(lat)
860
+ all_lons.append(lon)
861
+
862
+ # Create hover text with location name and info
863
+ hover_text = f"<b>{loc}</b>{additional_info}"
864
+ hover_texts.append(hover_text)
865
+
866
+ processed_count += 1
867
+ except Exception as e:
868
+ print(f"Error processing location {loc}: {str(e)}")
869
+
870
+ # Create Plotly map
871
+ if len(all_lats) > 0:
872
+ fig = go.Figure()
873
+
874
+ # Add scatter mapbox points
875
+ fig.add_trace(go.Scattermapbox(
876
+ lat=all_lats,
877
+ lon=all_lons,
878
+ mode='markers',
879
+ marker=go.scattermapbox.Marker(
880
+ size=10,
881
+ color='blue'
882
+ ),
883
+ text=hover_texts,
884
+ hoverinfo="text"
885
+ ))
886
+
887
+ # Configure map layout
888
+ fig.update_layout(
889
+ mapbox_style="open-street-map",
890
+ mapbox=dict(
891
+ center={"lat": sum(all_lats)/len(all_lats) if all_lats else 20,
892
+ "lon": sum(all_lons)/len(all_lons) if all_lons else 0},
893
+ zoom=3
894
+ ),
895
+ margin={"r":0,"t":0,"l":0,"b":0},
896
+ height=600
897
+ )
898
+
899
+ return fig, processed_count
900
+ else:
901
+ # Create empty figure if no coordinates found
902
+ fig = go.Figure()
903
+ fig.update_layout(
904
+ mapbox_style="open-street-map",
905
+ mapbox=dict(
906
+ center={"lat": 20, "lon": 0},
907
+ zoom=2
908
+ ),
909
+ margin={"r":0,"t":0,"l":0,"b":0},
910
+ height=600,
911
+ annotations=[
912
+ dict(
913
+ text="No locations found to display",
914
+ showarrow=False,
915
+ xref="paper",
916
+ yref="paper",
917
+ x=0.5,
918
+ y=0.5
919
+ )
920
+ ]
921
+ )
922
+ return fig, 0
923
+
924
+ # To use this in your Gradio app, modify your code to use gr.Plot instead of gr.HTML:
925
+
926
  with gr.TabItem("📍 Visualisierung von strukturierten Daten"):
927
  gr.HTML("""
928
  <div class="info-box">
 
956
  )
957
 
958
  with gr.Column():
959
+ # Replace HTML with Plot component
960
+ map_output = gr.Plot(
961
+ label="Interaktive Karte"
 
 
 
 
 
 
 
 
 
962
  )
 
963
 
964
+ # Modify your process_and_map function to use the new create_map_plotly function
965
  def process_and_map(file, column):
966
  if file is None:
967
  return None, "Hier bitte die Excel-Tabelle hochladen", None
968
 
969
  try:
970
+ # Load the Excel file
971
+ if hasattr(file, 'name'):
972
+ df = pd.read_excel(file.name)
973
+ elif isinstance(file, bytes):
974
+ df = pd.read_excel(io.BytesIO(file))
 
 
 
 
975
  else:
976
+ df = pd.read_excel(file)
977
+
978
+ if column not in df.columns:
979
+ return None, f"Spalte '{column}' wurde in der Excel-Datei nicht gefunden.", None
980
+
981
+ # Create map using Plotly
982
+ fig, processed_count = create_map_plotly(df, column)
983
+
984
+ # Save processed data to Excel
985
+ with tempfile.NamedTemporaryFile(suffix=".xlsx", delete=False) as tmp:
986
+ processed_path = tmp.name
987
+ df.to_excel(processed_path, index=False)
988
+
989
+ stats = f"Gefunden: {processed_count} Orte"
990
+
991
+ return fig, stats, processed_path
992
  except Exception as e:
993
  import traceback
994
  trace = traceback.format_exc()
 
1000
  inputs=[excel_file, places_column],
1001
  outputs=[map_output, stats_output, processed_file]
1002
  )
1003
+ """
1004
 
1005
  gr.HTML("""
1006
  <div style="text-align: center; margin-top: 2rem; padding-top: 1rem; border-top: 1px solid #eee; font-size: 0.9rem; color: #666;">