Add OSM Track Harvesting Policy and demo database initialization script
- Updated documentation to include OSM Track Harvesting Policy with details on railway types, service filters, usage filters, and geometry guardrails. - Introduced a new script `init_demo_db.py` to automate the database setup process, including environment checks, running migrations, and loading OSM fixtures for demo data.
This commit is contained in:
@@ -13,6 +13,7 @@ from typing import Any, Iterable, Mapping, Sequence
|
||||
from geoalchemy2.elements import WKBElement, WKTElement
|
||||
from geoalchemy2.shape import to_shape
|
||||
|
||||
from backend.app.core.osm_config import TRACK_STATION_SNAP_RADIUS_METERS
|
||||
from backend.app.db.session import SessionLocal
|
||||
from backend.app.models import TrackCreate
|
||||
from backend.app.repositories import StationRepository, TrackRepository
|
||||
@@ -133,26 +134,40 @@ def load_tracks(tracks: Iterable[ParsedTrack], commit: bool = True) -> int:
|
||||
|
||||
for track_data in tracks:
|
||||
start_station = _nearest_station(
|
||||
track_data.coordinates[0], station_index)
|
||||
track_data.coordinates[0],
|
||||
station_index,
|
||||
TRACK_STATION_SNAP_RADIUS_METERS,
|
||||
)
|
||||
end_station = _nearest_station(
|
||||
track_data.coordinates[-1], station_index)
|
||||
track_data.coordinates[-1],
|
||||
station_index,
|
||||
TRACK_STATION_SNAP_RADIUS_METERS,
|
||||
)
|
||||
|
||||
if not start_station or not end_station:
|
||||
continue
|
||||
|
||||
if start_station.id == end_station.id:
|
||||
continue
|
||||
|
||||
pair = (start_station.id, end_station.id)
|
||||
if pair in existing_pairs:
|
||||
continue
|
||||
|
||||
length = track_data.length_meters or _polyline_length(
|
||||
track_data.coordinates)
|
||||
max_speed = (
|
||||
int(round(track_data.max_speed_kph))
|
||||
if track_data.max_speed_kph is not None
|
||||
else None
|
||||
)
|
||||
create_schema = TrackCreate(
|
||||
name=track_data.name,
|
||||
start_station_id=start_station.id,
|
||||
end_station_id=end_station.id,
|
||||
coordinates=track_data.coordinates,
|
||||
length_meters=length,
|
||||
max_speed_kph=track_data.max_speed_kph,
|
||||
max_speed_kph=max_speed,
|
||||
status=track_data.status,
|
||||
is_bidirectional=track_data.is_bidirectional,
|
||||
)
|
||||
@@ -170,7 +185,9 @@ def load_tracks(tracks: Iterable[ParsedTrack], commit: bool = True) -> int:
|
||||
|
||||
|
||||
def _nearest_station(
|
||||
coordinate: tuple[float, float], stations: Sequence[StationRef]
|
||||
coordinate: tuple[float, float],
|
||||
stations: Sequence[StationRef],
|
||||
max_distance_meters: float,
|
||||
) -> StationRef | None:
|
||||
best_station: StationRef | None = None
|
||||
best_distance = math.inf
|
||||
@@ -180,7 +197,9 @@ def _nearest_station(
|
||||
if distance < best_distance:
|
||||
best_station = station
|
||||
best_distance = distance
|
||||
return best_station
|
||||
if best_distance <= max_distance_meters:
|
||||
return best_station
|
||||
return None
|
||||
|
||||
|
||||
def _build_station_index(stations: Iterable[Any]) -> list[StationRef]:
|
||||
@@ -192,11 +211,15 @@ def _build_station_index(stations: Iterable[Any]) -> list[StationRef]:
|
||||
point = _to_point(location)
|
||||
if point is None:
|
||||
continue
|
||||
latitude = getattr(point, "y", None)
|
||||
longitude = getattr(point, "x", None)
|
||||
if latitude is None or longitude is None:
|
||||
continue
|
||||
index.append(
|
||||
StationRef(
|
||||
id=str(station.id),
|
||||
latitude=float(point.y),
|
||||
longitude=float(point.x),
|
||||
latitude=float(latitude),
|
||||
longitude=float(longitude),
|
||||
)
|
||||
)
|
||||
return index
|
||||
|
||||
Reference in New Issue
Block a user