"""Road layer assembly from osm2streets GeoJSON and OSM fallback ways.""" import json import os from osmassets.geom import clip_polygon, feature_in_bounds, geometry_rings from osmassets.mesh import MeshBatch, add_polyline def assemble_geojson_layer(path, layer_id, projector, collection, material, z, property_filter=None): if not os.path.exists(path): return 0 with open(path, "r", encoding="utf-8") as handle: data = json.load(handle) batch = MeshBatch("Road_" + layer_id, collection, material) b = projector.bounds xmin, ymin = projector.xy((b["min_lon"], b["min_lat"])) xmax, ymax = projector.xy((b["max_lon"], b["max_lat"])) count = 0 for feature in data.get("features", []): if property_filter and not property_filter(feature.get("properties", {})): continue if not feature_in_bounds(feature, projector): continue for ring in geometry_rings(feature.get("geometry")): points = [projector.xy(pair) for pair in ring] points = clip_polygon(points, xmin, xmax, ymin, ymax) if len(points) >= 3: batch.add_polygon(points, z) count += 1 batch.finish() return count def assemble_osm_fallback(ways, projector, collection, material): for way in ways: highway = way["tags"].get("highway") if highway and len(way["coords"]) >= 2: width = {"secondary": 7.0, "residential": 5.5, "service": 3.5}.get(highway, 4.0) add_polyline("OSM_Road_" + str(way["id"]), way["coords"], projector, collection, material, width, 0.03)