feat: Enhance track model and import functionality
- Added new fields to TrackModel: status, is_bidirectional, and coordinates. - Updated network service to handle new track attributes and geometry extraction. - Introduced CLI scripts for importing and loading tracks from OpenStreetMap. - Implemented normalization of track elements to ensure valid geometries. - Enhanced tests for track model, network service, and import/load scripts. - Updated frontend to accommodate new track attributes and improve route computation. - Documented OSM ingestion process in architecture and runtime views.
This commit is contained in:
@@ -8,9 +8,10 @@ from geoalchemy2.elements import WKBElement, WKTElement
|
||||
from geoalchemy2.shape import to_shape
|
||||
|
||||
try: # pragma: no cover - optional dependency guard
|
||||
from shapely.geometry import Point # type: ignore
|
||||
from shapely.geometry import LineString, Point # type: ignore
|
||||
except ImportError: # pragma: no cover - allow running without shapely at import time
|
||||
Point = None # type: ignore[assignment]
|
||||
LineString = None # type: ignore[assignment]
|
||||
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -51,6 +52,12 @@ def _fallback_snapshot() -> dict[str, list[dict[str, object]]]:
|
||||
end_station_id="station-2",
|
||||
length_meters=289000.0,
|
||||
max_speed_kph=230.0,
|
||||
status="operational",
|
||||
is_bidirectional=True,
|
||||
coordinates=[
|
||||
(stations[0].latitude, stations[0].longitude),
|
||||
(stations[1].latitude, stations[1].longitude),
|
||||
],
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
)
|
||||
@@ -134,6 +141,20 @@ def get_network_snapshot(session: Session) -> dict[str, list[dict[str, object]]]
|
||||
|
||||
track_models: list[TrackModel] = []
|
||||
for track in tracks_entities:
|
||||
coordinates: list[tuple[float, float]] = []
|
||||
geometry = track.track_geometry
|
||||
shape = (
|
||||
to_shape(cast(WKBElement | WKTElement, geometry))
|
||||
if geometry is not None and LineString is not None
|
||||
else None
|
||||
)
|
||||
if LineString is not None and shape is not None and isinstance(shape, LineString):
|
||||
coords_list: list[tuple[float, float]] = []
|
||||
for coord in shape.coords:
|
||||
lon = float(coord[0])
|
||||
lat = float(coord[1])
|
||||
coords_list.append((lat, lon))
|
||||
coordinates = coords_list
|
||||
track_models.append(
|
||||
TrackModel(
|
||||
id=str(track.id),
|
||||
@@ -141,6 +162,9 @@ def get_network_snapshot(session: Session) -> dict[str, list[dict[str, object]]]
|
||||
end_station_id=str(track.end_station_id),
|
||||
length_meters=_to_float(track.length_meters),
|
||||
max_speed_kph=_to_float(track.max_speed_kph),
|
||||
status=track.status,
|
||||
is_bidirectional=track.is_bidirectional,
|
||||
coordinates=coordinates,
|
||||
created_at=cast(datetime, track.created_at),
|
||||
updated_at=cast(datetime, track.updated_at),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user