@@ -277,7 +277,7 @@ impl<'a> NodeToTrack<'a> {
277
277
}
278
278
279
279
pub fn signals (
280
- osm_pbf_in : std:: path:: PathBuf ,
280
+ osm_pbf_in : & std:: path:: PathBuf ,
281
281
nodes_to_tracks : & NodeToTrack ,
282
282
adjacencies : & HashMap < osm4routing:: NodeId , NodeAdjacencies > ,
283
283
) -> Vec < Signal > {
@@ -456,6 +456,69 @@ pub fn catenaries(edge: &Edge) -> Option<Catenary> {
456
456
} )
457
457
}
458
458
459
+ pub fn operational_points (
460
+ osm_pbf_in : & std:: path:: PathBuf ,
461
+ nodes_to_tracks : & NodeToTrack ,
462
+ ) -> Vec < OperationalPoint > {
463
+ let file = std:: fs:: File :: open ( osm_pbf_in) . unwrap ( ) ;
464
+ let mut pbf = osmpbfreader:: OsmPbfReader :: new ( file) ;
465
+ pbf. iter ( )
466
+ . flatten ( )
467
+ . filter ( |obj| obj. tags ( ) . contains ( "public_transport" , "stop_area" ) ) // https://wiki.openstreetmap.org/wiki/Tag:public_transport%3Dstop_area
468
+ . flat_map ( |obj| match obj {
469
+ osmpbfreader:: OsmObj :: Relation ( rel) => Some ( rel) , // Only consider OSM relations
470
+ _ => None , // Discard Nodes and Ways
471
+ } )
472
+ . map ( |rel| {
473
+ let parts = rel
474
+ . refs
475
+ . iter ( )
476
+ . filter ( |r| r. role == "stop" ) // We ignore other members of the relation
477
+ . flat_map ( |r| match r. member {
478
+ osmpbfreader:: OsmId :: Node ( id) => Some ( id) ,
479
+ _ => {
480
+ warn ! ( "OpenStreetMap relation ({}) has a member ({:?}) with role `stop` that isn’t a node" , rel. id. 0 , r. member) ;
481
+ None
482
+ } ,
483
+ } )
484
+ . flat_map ( |node| {
485
+ nodes_to_tracks
486
+ . track_and_position ( node)
487
+ . map ( |( track, position) | OperationalPointPart { track, position } )
488
+ } )
489
+ . collect ( ) ;
490
+
491
+ OperationalPoint {
492
+ id : rel. id . 0 . to_string ( ) . into ( ) ,
493
+ parts,
494
+ extensions : OperationalPointExtensions {
495
+ identifier : identifier ( & rel. tags ) ,
496
+ sncf : None ,
497
+ } ,
498
+ }
499
+ } )
500
+ . collect ( )
501
+ }
502
+
503
+ fn identifier ( tags : & osmpbfreader:: Tags ) -> Option < OperationalPointIdentifierExtension > {
504
+ let uic = tags
505
+ . get ( "uic_ref" )
506
+ . and_then ( |uic| match i64:: from_str ( uic. as_str ( ) ) {
507
+ Ok ( uic) => Some ( uic) ,
508
+ Err ( _) => {
509
+ warn ! ( "Could not parse {uic} uic code as integer" ) ;
510
+ None
511
+ }
512
+ } )
513
+ . unwrap_or_default ( ) ;
514
+
515
+ tags. get ( "name" )
516
+ . map ( |name| OperationalPointIdentifierExtension {
517
+ name : name. as_str ( ) . into ( ) ,
518
+ uic,
519
+ } )
520
+ }
521
+
459
522
#[ cfg( test) ]
460
523
mod tests {
461
524
use osm4routing:: Coord ;
0 commit comments