| 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 |
| start_angle = azimuth - (arc_angle / 2) |
| end_angle = azimuth + (arc_angle / 2) |
|
|
| coords = [(lon, lat)] |
|
|
| |
| 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)) |
|
|
| |
| pol = kml.newpolygon(name=name, outerboundaryis=coords) |
|
|
| |
| 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 |
| pol.style.polystyle.outline = 1 |
| pol.style.linestyle.color = "ff000000" |
|
|
|
|
| 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() |
|
|
| |
| df_sorted = df.sort_values( |
| by="size", ascending=False |
| ) |
|
|
| for _, row in df_sorted.iterrows(): |
| code, lon, lat = row["code"], row["Longitude"], row["Latitude"] |
|
|
| |
| 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 |
| 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() |
| kml_data.write(kml_str.encode("utf-8")) |
| kml_data.seek(0) |
| return kml_data |
|
|