✨ Handle IDFM stop areas shapes
This commit is contained in:
@@ -16,6 +16,7 @@ from aiohttp import ClientSession
|
|||||||
from msgspec import ValidationError
|
from msgspec import ValidationError
|
||||||
from msgspec.json import Decoder
|
from msgspec.json import Decoder
|
||||||
from rich import print
|
from rich import print
|
||||||
|
from shapefile import Reader as ShapeFileReader, ShapeRecord
|
||||||
|
|
||||||
from ..db import Database
|
from ..db import Database
|
||||||
from ..models import ConnectionArea, Line, LinePicto, Stop, StopArea, StopShape
|
from ..models import ConnectionArea, Line, LinePicto, Stop, StopArea, StopShape
|
||||||
@@ -76,7 +77,19 @@ class IdfmInterface:
|
|||||||
|
|
||||||
async def startup(self) -> None:
|
async def startup(self) -> None:
|
||||||
BATCH_SIZE = 10000
|
BATCH_SIZE = 10000
|
||||||
STEPS: tuple[tuple[Type[Stop] | Type[StopArea], Callable, Callable], ...] = (
|
STEPS: tuple[
|
||||||
|
tuple[
|
||||||
|
Type[ConnectionArea] | Type[Stop] | Type[StopArea] | Type[StopShape],
|
||||||
|
Callable,
|
||||||
|
Callable,
|
||||||
|
],
|
||||||
|
...,
|
||||||
|
] = (
|
||||||
|
(
|
||||||
|
StopShape,
|
||||||
|
self._request_stop_shapes,
|
||||||
|
IdfmInterface._format_idfm_stop_shapes,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
ConnectionArea,
|
ConnectionArea,
|
||||||
self._request_idfm_connection_areas,
|
self._request_idfm_connection_areas,
|
||||||
@@ -220,6 +233,14 @@ class IdfmInterface:
|
|||||||
print(f"{area_stop_assos_nb} stop area <-> stop ({total_assos_nb = } found)")
|
print(f"{area_stop_assos_nb} stop area <-> stop ({total_assos_nb = } found)")
|
||||||
print(f"{conn_stop_assos_nb} stop area <-> stop ({total_assos_nb = } found)")
|
print(f"{conn_stop_assos_nb} stop area <-> stop ({total_assos_nb = } found)")
|
||||||
|
|
||||||
|
# TODO: This method is synchronous due to the shapefile library.
|
||||||
|
# It's not a blocking issue but it could be nice to find an alternative.
|
||||||
|
async def _request_stop_shapes(self) -> AsyncIterator[ShapeRecord]:
|
||||||
|
# TODO: Use HTTP
|
||||||
|
with ShapeFileReader("./tests/datasets/REF_LDA.zip") as reader:
|
||||||
|
for record in reader.shapeRecords():
|
||||||
|
yield record
|
||||||
|
|
||||||
async def _request_idfm_stops(self) -> AsyncIterator[IdfmStop]:
|
async def _request_idfm_stops(self) -> AsyncIterator[IdfmStop]:
|
||||||
# headers = {"Accept": "application/json", "apikey": self._api_key}
|
# headers = {"Accept": "application/json", "apikey": self._api_key}
|
||||||
# async with ClientSession(headers=headers) as session:
|
# async with ClientSession(headers=headers) as session:
|
||||||
@@ -436,6 +457,16 @@ class IdfmInterface:
|
|||||||
changed_ts=int(connection_area.zdcchanged.timestamp()),
|
changed_ts=int(connection_area.zdcchanged.timestamp()),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _format_idfm_stop_shapes(*shape_records: ShapeRecord) -> Iterable[StopShape]:
|
||||||
|
for shape_record in shape_records:
|
||||||
|
yield StopShape(
|
||||||
|
id=shape_record.record[1],
|
||||||
|
type=shape_record.shape.shapeType,
|
||||||
|
bounding_box=list(shape_record.shape.bbox),
|
||||||
|
points=shape_record.shape.points,
|
||||||
|
)
|
||||||
|
|
||||||
async def render_line_picto(self, line: Line) -> tuple[None | str, None | str]:
|
async def render_line_picto(self, line: Line) -> tuple[None | str, None | str]:
|
||||||
begin_ts = time()
|
begin_ts = time()
|
||||||
line_picto_path = line_picto_format = None
|
line_picto_path = line_picto_format = None
|
||||||
|
@@ -1,5 +1,14 @@
|
|||||||
from .line import Line, TransportMode
|
from .line import Line, TransportMode
|
||||||
from .next_passage import NextPassage, NextPassages
|
from .next_passage import NextPassage, NextPassages
|
||||||
from .stop import Stop, StopArea
|
from .stop import Stop, StopArea, StopShape
|
||||||
|
|
||||||
__all__ = ["Line", "NextPassage", "NextPassages", "Stop", "StopArea", "TransportMode"]
|
|
||||||
|
__all__ = [
|
||||||
|
"Line",
|
||||||
|
"NextPassage",
|
||||||
|
"NextPassages",
|
||||||
|
"Stop",
|
||||||
|
"StopArea",
|
||||||
|
"StopShape",
|
||||||
|
"TransportMode",
|
||||||
|
]
|
||||||
|
@@ -23,3 +23,10 @@ class StopArea(BaseModel):
|
|||||||
type: StopAreaType
|
type: StopAreaType
|
||||||
lines: list[str] # SNCF lines are linked to stop areas and not stops.
|
lines: list[str] # SNCF lines are linked to stop areas and not stops.
|
||||||
stops: list[Stop]
|
stops: list[Stop]
|
||||||
|
|
||||||
|
|
||||||
|
class StopShape(BaseModel):
|
||||||
|
id: int
|
||||||
|
type: int
|
||||||
|
bbox: list[float]
|
||||||
|
points: list[tuple[float, float]]
|
||||||
|
@@ -16,6 +16,7 @@ fastapi = "^0.88.0"
|
|||||||
uvicorn = "^0.20.0"
|
uvicorn = "^0.20.0"
|
||||||
asyncpg = "^0.27.0"
|
asyncpg = "^0.27.0"
|
||||||
msgspec = "^0.12.0"
|
msgspec = "^0.12.0"
|
||||||
|
pyshp = "^2.3.1"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
Reference in New Issue
Block a user