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

71 lines
2.2 KiB
Python

import osmnx as ox
import shapely
import random
import uuid
def generate_osm_city_data(lat, lon, dist=400, scale=1.0):
print(f"🏙️ Fetching OSM buildings at ({lat}, {lon})")
scale_factor = scale # Shrinks the city to make the camera look like a giant
# ————— BUILDINGS —————
tags = {"building": True}
gdf = ox.features_from_point((lat, lon), tags=tags, dist=dist)
gdf = gdf[gdf.geometry.type.isin(["Polygon", "MultiPolygon"])].copy()
gdf = gdf.to_crs(epsg=3857)
gdf["centroid"] = gdf.geometry.centroid
status_options = ["OK", "Warning", "Critical", "Offline"]
raw_buildings = []
for i, row in gdf.iterrows():
centroid = row["centroid"]
polygon = row["geometry"]
try:
height = float(row.get("height", None))
except:
try:
height = float(row.get("building:levels", 3)) * 3.2
except:
height = 10.0
building_id = f"BLD-{uuid.uuid4().hex[:6].upper()}"
status = random.choice(status_options)
raw_buildings.append({
"id": building_id,
"raw_x": centroid.x,
"raw_z": centroid.y,
"width": polygon.bounds[2] - polygon.bounds[0],
"depth": polygon.bounds[3] - polygon.bounds[1],
"height": height,
"color": "#8a2be2",
"status": status,
})
# ————— CENTER AND SCALE —————
if raw_buildings:
avg_x = sum(b['raw_x'] for b in raw_buildings) / len(raw_buildings)
avg_z = sum(b['raw_z'] for b in raw_buildings) / len(raw_buildings)
buildings = []
for b in raw_buildings:
buildings.append({
"id": b['id'],
"position_x": (b['raw_x'] - avg_x) * scale_factor,
"position_z": (b['raw_z'] - avg_z) * scale_factor,
"width": b['width'] * scale_factor,
"depth": b['depth'] * scale_factor,
"height": b['height'] * scale_factor,
"color": b['color'],
"status": b['status'],
})
else:
buildings = []
return {
"buildings": buildings,
}