Spaces:
Sleeping
Sleeping
| import io | |
| import math | |
| import numpy as np | |
| import pandas as pd | |
| import simplekml | |
| def create_sector(kml: simplekml.Kml, row, arc_angle=65): | |
| """Create a sector shape for the telecom antenna in KML with sector details.""" | |
| code, name, azimuth, lon, lat, size, color = ( | |
| row["code"], | |
| row["name"], | |
| row["Azimut"], | |
| row["Longitude"], | |
| row["Latitude"], | |
| row["size"], | |
| row["color"], | |
| ) | |
| num_points = 20 # Number of points for smooth arc | |
| start_angle = azimuth - (arc_angle / 2) | |
| end_angle = azimuth + (arc_angle / 2) | |
| coords = [(lon, lat)] # Start with the site location (center point) | |
| # Generate points for the sector arc | |
| for angle in np.linspace(start_angle, end_angle, num_points): | |
| angle_rad = math.radians(angle) | |
| arc_lon = lon + (size / 111320) * math.sin(angle_rad) | |
| arc_lat = lat + (size / 111320) * math.cos(angle_rad) | |
| coords.append((arc_lon, arc_lat)) | |
| coords.append((lon, lat)) # Close the polygon | |
| # Create the sector polygon | |
| pol = kml.newpolygon(name=name, outerboundaryis=coords) | |
| # Dynamically create the description from all DataFrame columns | |
| description = "<b>Sector Details:</b><br>" | |
| for column, value in row.items(): | |
| description += f"<b>{column}:</b> {value}<br>" | |
| pol.description = description | |
| pol.style.polystyle.color = color # Set color from DataFrame | |
| pol.style.polystyle.outline = 1 # Outline enabled | |
| pol.style.linestyle.color = "ff000000" # Black outline | |
| def generate_kml_from_df(df: pd.DataFrame): | |
| """Generate a KML file from a Pandas DataFrame for telecom sectors.""" | |
| kml = simplekml.Kml() | |
| site_added = set() # Keep track of sites already added to avoid duplicates | |
| # Sort the DataFrame to ensure 900 MHz (smaller) is drawn last (on top) | |
| df_sorted = df.sort_values( | |
| by="size", ascending=False | |
| ) # Larger first, smaller on top | |
| for _, row in df_sorted.iterrows(): | |
| code, lon, lat = row["code"], row["Longitude"], row["Latitude"] | |
| # Add site name as a point only once | |
| if code not in site_added: | |
| pnt = kml.newpoint(name=code, coords=[(lon, lat)]) | |
| pnt.style.iconstyle.icon.href = ( | |
| "http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png" | |
| ) | |
| pnt.style.labelstyle.scale = 1.2 # Adjust label size | |
| pnt.description = f"Site: {code}<br>Location: {lat}, {lon}" | |
| site_added.add(code) | |
| create_sector(kml, row) | |
| kml_data = io.BytesIO() | |
| kml_str = kml.kml() # Get KML as string | |
| kml_data.write(kml_str.encode("utf-8")) # Write KML to BytesIO | |
| kml_data.seek(0) # Move to beginning of BytesIO | |
| return kml_data | |