feat: add OSM turn lane arrows
This commit is contained in:
@@ -152,7 +152,10 @@ def normalize_file(input_path, tolerance):
|
||||
with input_path.open("r", encoding="utf-8") as handle:
|
||||
collection = json.load(handle)
|
||||
|
||||
for index, feature in enumerate(collection.get("features", [])):
|
||||
collection["features"] = merge_custom_turn_lane_arrow_components(
|
||||
collection.get("features", [])
|
||||
)
|
||||
for index, feature in enumerate(collection["features"]):
|
||||
geometry = ogr.CreateGeometryFromJson(json.dumps(feature.get("geometry", {})))
|
||||
if geometry is None or geometry.IsEmpty():
|
||||
raise ValueError(f"feature {index} has no usable geometry")
|
||||
@@ -171,6 +174,49 @@ def normalize_file(input_path, tolerance):
|
||||
temp_path.replace(input_path)
|
||||
|
||||
|
||||
def merge_custom_turn_lane_arrow_components(features):
|
||||
"""Restore each imported SVG icon before QGIS assigns its single outline."""
|
||||
grouped = {}
|
||||
for feature in features:
|
||||
properties = feature.get("properties", {})
|
||||
arrow_id = properties.get("custom_arrow_id")
|
||||
if properties.get("source") == "osm_turn_lanes" and arrow_id:
|
||||
grouped.setdefault(arrow_id, []).append(feature)
|
||||
|
||||
merged_ids = set()
|
||||
output = []
|
||||
for feature in features:
|
||||
properties = feature.get("properties", {})
|
||||
arrow_id = properties.get("custom_arrow_id")
|
||||
if properties.get("source") != "osm_turn_lanes" or not arrow_id:
|
||||
output.append(feature)
|
||||
continue
|
||||
if arrow_id in merged_ids:
|
||||
continue
|
||||
merged_ids.add(arrow_id)
|
||||
components = grouped[arrow_id]
|
||||
multi = ogr.Geometry(ogr.wkbMultiPolygon)
|
||||
for component in components:
|
||||
geometry = ogr.CreateGeometryFromJson(
|
||||
json.dumps(component.get("geometry", {}))
|
||||
)
|
||||
if geometry is None or geometry.IsEmpty() or geometry.GetGeometryName() != "POLYGON":
|
||||
raise ValueError(f"custom arrow {arrow_id} has an invalid component")
|
||||
multi.AddGeometry(geometry)
|
||||
united = multi.UnionCascaded()
|
||||
if united is None or united.IsEmpty() or united.GetGeometryName() != "POLYGON":
|
||||
raise ValueError(
|
||||
f"custom arrow {arrow_id} components did not form one Polygon"
|
||||
)
|
||||
merged = dict(components[0])
|
||||
merged["properties"] = dict(components[0].get("properties", {}))
|
||||
merged["properties"].pop("arrow_part", None)
|
||||
merged["properties"]["component_count"] = len(components)
|
||||
merged["geometry"] = json.loads(united.ExportToJson())
|
||||
output.append(merged)
|
||||
return output
|
||||
|
||||
|
||||
def main():
|
||||
args = cli_args()
|
||||
if args.outline_simplify_meters < 0:
|
||||
|
||||
Reference in New Issue
Block a user