Skip to content

Commit d93869d

Browse files
committed
python: add stubs
This has been generated by https://github.com/Jij-Inc/pyo3-stub-gen However, there is a chain of dependencies that makes it hard to include the build process in this commit. That is why we offer for now a static file (as suggested in https://pyo3.rs/v0.16.4/python_typing_hints.html) Signed-off-by: Tristram Gräbener <[email protected]>
1 parent 9f4518f commit d93869d

File tree

2 files changed

+235
-0
lines changed

2 files changed

+235
-0
lines changed

python/liblrs_python.pyi

+205
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# This file is automatically generated by pyo3_stub_gen
2+
# ruff: noqa: E501, F401
3+
4+
import typing
5+
6+
class Anchor:
7+
r"""
8+
An `Anchor` is a reference point for a given [`Curve`].
9+
It can be a milestone, a bridge…
10+
"""
11+
name: str
12+
position: typing.Optional[Point]
13+
curve_position: float
14+
scale_position: float
15+
16+
class AnchorOnLrm:
17+
r"""
18+
The linear position of an anchor doesn’t always match the measured distance
19+
For example if a road was transformed into a bypass, resulting in a longer road,
20+
but measurements are kept the same
21+
The start of the curve might also be different from the `0` of the LRM
22+
"""
23+
def __new__(cls,anchor_index:int, distance_along_lrm:float): ...
24+
...
25+
26+
class Builder:
27+
def __new__(cls,): ...
28+
def add_node(self, id:str, coord:Point, properties:typing.Mapping[str, str]) -> int:
29+
r"""
30+
Add a new topological node (e.g. a railway switch)
31+
"""
32+
...
33+
34+
def add_anchor(self, id:str, coord:Point, properties:typing.Mapping[str, str], name:typing.Optional[str]) -> int:
35+
r"""
36+
Add a new anchor by its cooordinates
37+
"""
38+
...
39+
40+
def add_projected_anchor(self, id:str, position_on_curve:float, properties:typing.Mapping[str, str], name:typing.Optional[str]) -> int:
41+
r"""
42+
Add a new anchor by its position along the curve
43+
"""
44+
...
45+
46+
def add_segment(self, id:str, geometry:typing.Sequence[Point], start_node_index:int, end_node_index:int) -> int:
47+
r"""
48+
Add a new segment
49+
50+
The geometry represents the curve
51+
start_node_index and end_node_index are the topological extremeties returned by `add_node`
52+
"""
53+
...
54+
55+
def add_traversal(self, traversal_id:str, segments:typing.Sequence[SegmentOfTraversal]) -> None:
56+
r"""
57+
Add a traversal
58+
59+
segments represent the curve of the traversal
60+
"""
61+
...
62+
63+
def add_lrm(self, id:str, traversal_index:int, anchors:typing.Sequence[AnchorOnLrm], properties:typing.Mapping[str, str]) -> None:
64+
r"""
65+
Add a linear referencing model
66+
67+
It is composed by the traversal identified by traversa_index (that represents the curve)
68+
and the anchors (that represent the milestones)
69+
"""
70+
...
71+
72+
def get_traversal_indexes(self) -> dict[str, int]:
73+
r"""
74+
List all the traversals by their id and index
75+
"""
76+
...
77+
78+
def read_from_osm(self, input_osm_file:pathlib.Path, lrm_tag:str, required:typing.Sequence[tuple[str, str]], to_reject:typing.Sequence[tuple[str, str]]) -> None:
79+
r"""
80+
Read the topology from an OpenStreetMap source
81+
82+
It reads the nodes, segments and traversals.
83+
"""
84+
...
85+
86+
def save(self, out_file:pathlib.Path, properties:typing.Mapping[str, str]) -> None:
87+
r"""
88+
Save the lrs to a file
89+
"""
90+
...
91+
92+
def euclidean_distance(self, lrm_index_a:int, lrm_index_b:int) -> float:
93+
r"""
94+
Compute the euclidean distance between two lrms
95+
"""
96+
...
97+
98+
def get_nodes_of_traversal(self, lrm_index:int) -> list[int]:
99+
r"""
100+
List all the node indices of a traversal
101+
"""
102+
...
103+
104+
def get_node_coord(self, node_index:int) -> Point:
105+
r"""
106+
Get the coordinates of a node identified by its index
107+
"""
108+
...
109+
110+
def project(self, lrm_index:int, point:Point) -> typing.Optional[float]:
111+
r"""
112+
Project a point on a the curve of an lrm
113+
114+
Return a value between 0 and 1, both included
115+
Return None if the curve of the traversal is not defined
116+
"""
117+
...
118+
119+
def reverse(self, lrm_index:int) -> None:
120+
r"""
121+
Reverse the orientation of the lrm
122+
123+
If it is composed by the segments (a, b)-(b, c) it will be (c, b)-(b, a)
124+
"""
125+
...
126+
127+
128+
class LrmScaleMeasure:
129+
r"""
130+
Represent a position on an [`LrmScale`] relative as an `offset` to an [`Anchor`].
131+
"""
132+
anchor_name: str
133+
scale_offset: float
134+
def __new__(cls,anchor_name:str, scale_offset:float): ...
135+
136+
class Lrs:
137+
r"""
138+
Holds the whole Linear Referencing System.
139+
"""
140+
def __new__(cls,data:bytes): ...
141+
def lrm_len(self) -> int:
142+
r"""
143+
How many LRMs compose the LRS.
144+
"""
145+
...
146+
147+
def get_lrm_geom(self, index:int) -> list[Point]:
148+
r"""
149+
Return the geometry of the LRM.
150+
"""
151+
...
152+
153+
def get_lrm_scale_id(self, index:int) -> str:
154+
r"""
155+
 `id` of the [`LrmScale`].
156+
"""
157+
...
158+
159+
def get_anchors(self, lrm_index:int) -> list[Anchor]:
160+
r"""
161+
All the [`Anchor`]s of a LRM.
162+
"""
163+
...
164+
165+
def resolve(self, lrm_index:int, measure:LrmScaleMeasure) -> Point:
166+
r"""
167+
Get the position given a [`LrmScaleMeasure`].
168+
"""
169+
...
170+
171+
def locate_point(self, lrm_index:int, measure:LrmScaleMeasure) -> float:
172+
r"""
173+
Get the positon along the curve given a [`LrmScaleMeasure`]
174+
The value will be between 0.0 and 1.0, both included
175+
"""
176+
...
177+
178+
def resolve_range(self, lrm_index:int, from:LrmScaleMeasure, to:LrmScaleMeasure) -> list[Point]:
179+
r"""
180+
Given two [`LrmScaleMeasure`]s, return a range of [`Point`] that represent a line string.
181+
"""
182+
...
183+
184+
def find_lrm(self, lrm_id:str) -> typing.Optional[int]:
185+
r"""
186+
Given a ID returns the corresponding lrs index (or None if not found)
187+
"""
188+
...
189+
190+
191+
class Point:
192+
r"""
193+
A geographical [`Point`], it can be either a projected or spherical coordinates.
194+
"""
195+
x: float
196+
y: float
197+
def __new__(cls,x:float, y:float): ...
198+
199+
class SegmentOfTraversal:
200+
r"""
201+
A traversal is composed by segments
202+
"""
203+
def __new__(cls,segment_index:int, reversed:bool): ...
204+
...
205+

python/src/lib.rs

+30
Original file line numberDiff line numberDiff line change
@@ -285,16 +285,19 @@ struct Builder {
285285
#[pymethods]
286286
impl Builder {
287287
#[new]
288+
/// Instantiate a new builder
288289
fn new() -> Self {
289290
Self {
290291
inner: liblrs::builder::Builder::new(),
291292
}
292293
}
293294

295+
/// Add a new topological node (e.g. a railway switch)
294296
pub fn add_node(&mut self, id: &str, coord: Point, properties: Properties) -> usize {
295297
self.inner.add_node(id, coord.into(), properties)
296298
}
297299

300+
/// Add a new anchor by its cooordinates
298301
#[pyo3(signature = (id, coord, properties, name=None))]
299302
pub fn add_anchor(
300303
&mut self,
@@ -306,6 +309,7 @@ impl Builder {
306309
self.inner.add_anchor(id, name, coord.into(), properties)
307310
}
308311

312+
/// Add a new anchor by its position along the curve
309313
#[pyo3(signature = (id, position_on_curve, properties, name=None))]
310314
pub fn add_projected_anchor(
311315
&mut self,
@@ -318,6 +322,10 @@ impl Builder {
318322
.add_projected_anchor(id, name, position_on_curve, properties)
319323
}
320324

325+
/// Add a new segment
326+
///
327+
/// The geometry represents the curve
328+
/// start_node_index and end_node_index are the topological extremeties returned by `add_node`
321329
pub fn add_segment(
322330
&mut self,
323331
id: &str,
@@ -330,11 +338,18 @@ impl Builder {
330338
.add_segment(id, &geometry, start_node_index, end_node_index)
331339
}
332340

341+
/// Add a traversal
342+
///
343+
/// segments represent the curve of the traversal
333344
pub fn add_traversal(&mut self, traversal_id: &str, segments: Vec<SegmentOfTraversal>) {
334345
let segments: Vec<_> = segments.into_iter().map(|segment| segment.into()).collect();
335346
self.inner.add_traversal(traversal_id, &segments);
336347
}
337348

349+
/// Add a linear referencing model
350+
///
351+
/// It is composed by the traversal identified by traversa_index (that represents the curve)
352+
/// and the anchors (that represent the milestones)
338353
pub fn add_lrm(
339354
&mut self,
340355
id: &str,
@@ -347,10 +362,14 @@ impl Builder {
347362
.add_lrm(id, traversal_index, &anchors, properties)
348363
}
349364

365+
/// List all the traversals by their id and index
350366
pub fn get_traversal_indexes(&mut self) -> std::collections::HashMap<String, usize> {
351367
self.inner.get_traversal_indexes()
352368
}
353369

370+
/// Read the topology from an OpenStreetMap source
371+
///
372+
/// It reads the nodes, segments and traversals.
354373
pub fn read_from_osm(
355374
&mut self,
356375
input_osm_file: String,
@@ -362,29 +381,40 @@ impl Builder {
362381
.read_from_osm(&input_osm_file, &lrm_tag, required, to_reject)
363382
}
364383

384+
/// Save the lrs to a file
365385
pub fn save(&mut self, out_file: String, properties: Properties) {
366386
self.inner.save(&out_file, properties)
367387
}
368388

389+
/// Compute the euclidean distance between two lrms
369390
pub fn euclidean_distance(&self, lrm_index_a: usize, lrm_index_b: usize) -> f64 {
370391
self.inner.euclidean_distance(lrm_index_a, lrm_index_b)
371392
}
372393

394+
/// List all the node indices of a traversal
373395
pub fn get_nodes_of_traversal(&self, lrm_index: usize) -> Vec<usize> {
374396
self.inner.get_nodes_of_traversal(lrm_index).to_vec()
375397
}
376398

399+
/// Get the coordinates of a node identified by its index
377400
pub fn get_node_coord(&self, node_index: usize) -> Point {
378401
self.inner.get_node_coord(node_index).into()
379402
}
380403

404+
/// Project a point on a the curve of an lrm
405+
///
406+
/// Return a value between 0 and 1, both included
407+
/// Return None if the curve of the traversal is not defined
381408
pub fn project(&self, lrm_index: usize, point: Point) -> Option<f64> {
382409
self.inner
383410
.project(lrm_index, geo_types::point! {x: point.x, y: point.y})
384411
.map(|p| p.distance_along_curve)
385412
.ok()
386413
}
387414

415+
/// Reverse the orientation of the lrm
416+
///
417+
/// If it is composed by the segments (a, b)-(b, c) it will be (c, b)-(b, a)
388418
pub fn reverse(&mut self, lrm_index: usize) {
389419
self.inner.reverse(lrm_index)
390420
}

0 commit comments

Comments
 (0)