2025-05-11 23:21:12 -06:00

156 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import random
from .network import compute_mst_fiber_paths, compute_network_summary
GRID_SIZE = 5
SPACING = 15 # Distance between objects
def generate_com_con_city_data(lat, long):
"""
Generate a digital twin for a real-world city (e.g., Concepción).
Returns towers, fiber paths, wifi hotspots, and a summary.
"""
random.seed(f"{lat},{long}")
center_x = lat
center_z = long
towers = generate_towers(center_x, center_z)
fiber_paths = compute_mst_fiber_paths(towers)
wifi_hotspots = generate_wifi_hotspots(center_x, center_z)
summary = compute_network_summary(towers, fiber_paths, wifi_hotspots)
return {
'towers': towers,
'fiber_paths': fiber_paths,
'wifi_hotspots': wifi_hotspots,
'network_summary': summary,
}
def generate_towers(center_x, center_z, mode="streets"):
"""
Generate towers either in a 'grid' or at realistic 'streets' (mocked).
mode: "grid" | "streets"
"""
if mode == "streets":
return generate_street_corner_towers(center_x, center_z)
else:
return generate_grid_towers(center_x, center_z)
import osmnx as ox
def generate_street_corner_towers(center_x, center_z, min_towers=10):
"""
Get real intersections from OSM and convert them to local x/z positions
relative to center_x / center_z (in meters). Fallbacks to mocked layout if needed.
"""
print("📍 Starting generate_street_corner_towers()")
print(f"→ center_x: {center_x}, center_z: {center_z}")
point = (center_x, center_z)
print(f"→ Using real lat/lon: {point}")
try:
for dist in [100, 200, 500, 1000]:
print(f"🛰️ Trying OSM download at radius: {dist} meters...")
G = ox.graph_from_point(point, dist=dist, network_type='all')
G_undirected = G.to_undirected()
degrees = dict(G_undirected.degree())
intersections = [n for n, d in degrees.items() if d >= 3]
print(f" ✅ Found {len(intersections)} valid intersections.")
if len(intersections) >= min_towers:
break
else:
raise ValueError("No sufficient intersections found.")
nodes, _ = ox.graph_to_gdfs(G)
origin_lon = nodes.loc[intersections]['x'].mean()
origin_lat = nodes.loc[intersections]['y'].mean()
print(f"📌 Using origin_lon: {origin_lon:.6f}, origin_lat: {origin_lat:.6f} for local projection")
def latlon_to_sim(lon, lat):
dx = (lon - origin_lon) * 111320
dz = (lat - origin_lat) * 110540
return center_x + dx, center_z + dz
towers = []
for i, node_id in enumerate(intersections):
row = nodes.loc[node_id]
x_sim, z_sim = latlon_to_sim(row['x'], row['y'])
print(f" 🗼 Tower #{i+1} at sim position: x={x_sim:.2f}, z={z_sim:.2f}")
towers.append(make_tower(x_sim, z_sim, i + 1))
print(f"✅ Done. Total towers returned: {len(towers)}\n")
return towers
except Exception as e:
print(f"❌ OSM tower generation failed: {e}")
print("⚠️ Falling back to mocked tower layout.")
# Return 3x3 fixed grid as fallback
offsets = [(-30, -30), (-30, 0), (-30, 30),
(0, -30), (0, 0), (0, 30),
(30, -30), (30, 0), (30, 30)]
towers = []
for i, (dx, dz) in enumerate(offsets):
x = center_x + dx
z = center_z + dz
towers.append(make_tower(x, z, i + 1))
print(f"✅ Fallback returned {len(towers)} towers.\n")
return towers
def generate_grid_towers(center_x, center_z):
"""Generates a 5×5 grid of towers around the city center."""
towers = []
for i in range(GRID_SIZE):
for j in range(GRID_SIZE):
x = center_x + (i - GRID_SIZE // 2) * SPACING
z = center_z + (j - GRID_SIZE // 2) * SPACING
towers.append({
'id': len(towers) + 1,
'status': 'Active' if random.random() > 0.2 else 'Inactive',
'position_x': x,
'position_y': 0,
'position_z': z,
'height': random.randint(40, 60),
'range': random.randint(500, 1000),
'color': '#ff4500'
})
return towers
def generate_wifi_hotspots(center_x, center_z):
"""Places 10 Wi-Fi hotspots randomly around the city center."""
hotspots = []
bound = SPACING * GRID_SIZE / 2
for i in range(10):
x = center_x + random.uniform(-bound, bound)
z = center_z + random.uniform(-bound, bound)
hotspots.append({
'id': i + 1,
'position_x': x,
'position_y': 1.5,
'position_z': z,
'status': 'Online' if random.random() > 0.2 else 'Offline',
'radius': random.randint(1, 3),
'color': '#32cd32'
})
return hotspots
def make_tower(x, z, id):
return {
'id': id,
'status': 'Active',
'position_x': x,
'position_y': 0,
'position_z': z,
'height': 50,
'range': 1000,
'color': '#ff4500'
}