pub fn project_gnss(
positions: &[GnssPosition],
network: &RailwayNetwork,
config: &ProjectionConfig,
) -> Result<Vec<ProjectedPosition>>Expand description
Project GNSS positions onto railway network
Projects each GNSS position onto the nearest railway netelement, calculating the measure (distance along track) and perpendicular projection distance.
§Algorithm
- Find nearest netelement using R-tree spatial index
- Project GNSS point onto netelement LineString geometry
- Calculate measure from start of netelement
- Calculate perpendicular distance from point to line
- Emit warning if projection distance exceeds threshold
§Arguments
positions- Slice of GNSS positions with coordinates and timestampsnetwork- Railway network with spatial indexconfig- Projection configuration (warning threshold, CRS settings)
§Returns
Ok(Vec<ProjectedPosition>)- Successfully projected positionsErr(ProjectionError)- If projection fails (invalid geometry, CRS mismatch, etc.)
§Examples
use tp_core::{parse_gnss_csv, parse_network_geojson, RailwayNetwork};
use tp_core::{project_gnss, ProjectionConfig};
// Load data
let netelements = parse_network_geojson("network.geojson")?;
let network = RailwayNetwork::new(netelements)?;
let positions = parse_gnss_csv("gnss.csv", "EPSG:4326", "latitude", "longitude", "timestamp")?;
// Project with custom warning threshold
let config = ProjectionConfig {
projection_distance_warning_threshold: 100.0,
transform_crs: true,
suppress_warnings: false,
};
let projected = project_gnss(&positions, &network, &config)?;
// Check projection quality
for pos in &projected {
if pos.projection_distance_meters > 50.0 {
println!("Warning: large projection distance for {}", pos.netelement_id);
}
}§Performance
- O(n log m) where n = GNSS positions, m = netelements
- Spatial indexing enables efficient nearest-neighbor search
- Target: <10 seconds for 1000 positions × 50 netelements