Spaces:
Sleeping
Sleeping
| # utils.py | |
| import folium | |
| import branca.colormap as cm | |
| import geopandas as gpd | |
| import matplotlib.pyplot as plt | |
| from shapely.geometry import LineString, Point | |
| from shapely.errors import TopologicalError | |
| import warnings | |
| def plot_full_india_map(states_gdf): | |
| """Plot the full India map with state labels.""" | |
| fig, ax = plt.subplots(figsize=(8, 10)) | |
| states_gdf.boundary.plot(ax=ax, linewidth=0.8, edgecolor='black') | |
| states_gdf.plot(ax=ax, alpha=0.1) | |
| # Add labels | |
| for idx, row in states_gdf.iterrows(): | |
| if row.geometry.is_empty or row.geometry.centroid.is_empty: | |
| continue | |
| point = row.geometry.centroid | |
| ax.text(point.x, point.y, row['State'], fontsize=7, ha='center') | |
| ax.axis('off') | |
| return fig | |
| def draw_map_lines_with_labels( | |
| geo_data, | |
| selected_data, | |
| target_coords=None, | |
| line_style="Straight", | |
| label_field="State", | |
| show_boundaries=True | |
| ): | |
| """Draw map with optional lines and region labels.""" | |
| fig, ax = plt.subplots(figsize=(8, 10)) | |
| try: | |
| cleaned_geo = geo_data.copy() | |
| cleaned_geo['geometry'] = cleaned_geo['geometry'].buffer(0) # Clean invalid geometries | |
| except TopologicalError: | |
| cleaned_geo = geo_data # fallback | |
| # Plot background boundaries if toggled | |
| if show_boundaries: | |
| with warnings.catch_warnings(): | |
| warnings.simplefilter("ignore") | |
| try: | |
| gpd.GeoSeries(cleaned_geo.unary_union.boundary).plot(ax=ax, linewidth=0.4, edgecolor='lightgray') | |
| except Exception: | |
| pass | |
| # Plot selected regions with darker color | |
| selected_data.plot(ax=ax, color='skyblue', edgecolor='black', linewidth=0.8) | |
| # Draw labels only for selected data | |
| for _, row in selected_data.iterrows(): | |
| if row.geometry.is_empty: | |
| continue | |
| center = row.geometry.centroid | |
| label = row[label_field] if label_field in row else "Label" | |
| ax.text(center.x, center.y, label, fontsize=8, ha='center', weight='bold') | |
| # Draw lines if targets are given | |
| if target_coords and not selected_data.empty: | |
| for target in target_coords: | |
| for _, row in selected_data.iterrows(): | |
| try: | |
| centroid = row.geometry.centroid | |
| line = LineString([centroid, Point(target)]) | |
| linestyle = '-' if line_style == "Straight" else '--' if line_style == "Dashed" else ':' | |
| ax.plot(*line.xy, color='red', linestyle=linestyle) | |
| except Exception as e: | |
| continue | |
| ax.axis('off') | |
| return fig | |
| def add_hover_tooltips(map_obj, gdf, field_to_color, tooltip_fields, tooltip_aliases): | |
| min_val = gdf[field_to_color].min() | |
| max_val = gdf[field_to_color].max() | |
| colormap = cm.linear.YlGnBu_09.scale(min_val, max_val) | |
| colormap.caption = f"{field_to_color} Scale" | |
| folium.GeoJson( | |
| gdf, | |
| style_function=lambda feature: { | |
| 'fillColor': colormap(feature['properties'][field_to_color]), | |
| 'color': 'black', | |
| 'weight': 1, | |
| 'fillOpacity': 0.7, | |
| }, | |
| tooltip=folium.GeoJsonTooltip( | |
| fields=tooltip_fields, | |
| aliases=tooltip_aliases, | |
| localize=True, | |
| sticky=True | |
| ) | |
| ).add_to(map_obj) | |
| colormap.add_to(map_obj) | |