|
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 |
|
|