| Crates.io | tp-lib-cli |
| lib.rs | tp-lib-cli |
| version | 0.0.1 |
| created_at | 2026-01-08 15:11:02.623381+00 |
| updated_at | 2026-01-08 15:11:02.623381+00 |
| description | Command-line interface for GNSS track axis projection |
| homepage | |
| repository | https://github.com/Matdata-eu/tp-lib |
| max_upload_size | |
| id | 2030425 |
| size | 148,415 |
Command-line interface for projecting GNSS positions onto railway track netelements
# Build release binary
cargo build --release --package tp-cli --no-default-features
# Binary located at: target/release/tp-cli.exe (Windows) or target/release/tp-cli (Unix)
# Windows PowerShell
$env:PATH += ";$(pwd)\target\release"
# Unix/Linux/macOS
export PATH="$PATH:$(pwd)/target/release"
# Project CSV GNSS data onto railway network
tp-cli --gnss-file positions.csv \
--gnss-crs EPSG:4326 \
--network-file network.geojson
# Output defaults to CSV format on stdout
tp-cli --gnss-file positions.csv \
--gnss-crs EPSG:4326 \
--network-file network.geojson \
--output-format json > projected.geojson
# Warn only for projection distances > 100 meters
tp-cli --gnss-file positions.csv \
--gnss-crs EPSG:4326 \
--network-file network.geojson \
--warning-threshold 100.0
tp-cli --gnss-file data.csv \
--gnss-crs EPSG:4326 \
--network-file network.geojson \
--lat-col lat \
--lon-col lon \
--time-col ts
--gnss-file <FILE> (or -g)Path to GNSS input file (CSV or GeoJSON format).
CSV Example:
latitude,longitude,timestamp,altitude,hdop
50.8503,4.3517,2025-12-09T14:30:00+01:00,100.0,2.0
50.8504,4.3518,2025-12-09T14:30:01+01:00,100.5,2.1
Requirements:
2025-12-09T14:30:00+01:00)--network-file <FILE> (or -n)Path to railway network GeoJSON file.
Example:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"id": "NE001",
"crs": "EPSG:4326"
},
"geometry": {
"type": "LineString",
"coordinates": [
[4.35, 50.85],
[4.36, 50.86]
]
}
}
]
}
Requirements:
id property (unique identifier per netelement)crs property (EPSG code, e.g., "EPSG:4326")--gnss-crs <CRS>Coordinate Reference System of GNSS data (e.g., EPSG:4326).
Rules:
Common CRS codes:
EPSG:4326 - WGS84 (standard GPS coordinates)EPSG:31370 - Belgian Lambert 2008EPSG:3857 - Web Mercator--output-format <FORMAT> (or -o)Output format: csv or json. Default: csv.
CSV Output Example:
original_lat,original_lon,original_time,projected_lat,projected_lon,netelement_id,measure_meters,projection_distance_meters,crs
50.8503,4.3517,2025-12-09T14:30:00+01:00,50.85074,4.35148,NE001,132.54,51.31,EPSG:4326
JSON Output Example:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [4.35148, 50.85074]
},
"properties": {
"netelement_id": "NE001",
"measure_meters": 132.54,
"projection_distance_meters": 51.31,
"original_lat": 50.8503,
"original_lon": 4.3517,
"original_time": "2025-12-09T14:30:00+01:00",
"crs": "EPSG:4326"
}
}
]
}
--warning-threshold <METERS> (or -w)Distance threshold in meters for emitting projection warnings. Default: 50.0.
Warnings are printed to stderr when a GNSS position projects more than this distance from the track.
Example:
# Warn only for distances > 100m
tp-cli --gnss-file data.csv --gnss-crs EPSG:4326 --network-file network.geojson -w 100.0
--lat-col <COLUMN>Latitude column name in CSV input. Default: latitude.
--lon-col <COLUMN>Longitude column name in CSV input. Default: longitude.
--time-col <COLUMN>Timestamp column name in CSV input. Default: timestamp.
Example with custom columns:
tp-cli --gnss-file data.csv \
--gnss-crs EPSG:4326 \
--network-file network.geojson \
--lat-col lat --lon-col lon --time-col ts
Example:
# Redirect output to file, view warnings in terminal
tp-cli --gnss-file data.csv --gnss-crs EPSG:4326 --network-file network.geojson > output.csv
# Redirect both output and errors
tp-cli --gnss-file data.csv --gnss-crs EPSG:4326 --network-file network.geojson > output.csv 2> errors.log
tp-cli --gnss-file train_journey.csv \
--gnss-crs EPSG:4326 \
--network-file infrabel_network.geojson \
> projected_positions.csv
Input (train_journey.csv):
latitude,longitude,timestamp,speed,heading
50.8503,4.3517,2025-12-09T14:30:00+01:00,80.5,45
50.8504,4.3518,2025-12-09T14:30:01+01:00,81.2,46
Output (projected_positions.csv):
original_lat,original_lon,original_time,projected_lat,projected_lon,netelement_id,measure_meters,projection_distance_meters,crs
50.8503,4.3517,2025-12-09T14:30:00+01:00,50.85074,4.35148,NE001,132.54,51.31,EPSG:4326
50.8504,4.3518,2025-12-09T14:30:01+01:00,50.8508,4.3516,NE001,143.28,46.64,EPSG:4326
tp-cli --gnss-file positions.csv \
--gnss-crs EPSG:31370 \
--network-file network.geojson \
--output-format json \
--warning-threshold 75.0 \
> projected.geojson
# Input CSV has columns: lat, lon, time
tp-cli --gnss-file gps_data.csv \
--gnss-crs EPSG:4326 \
--network-file tracks.geojson \
--lat-col lat \
--lon-col lon \
--time-col time \
> output.csv
# Project positions and filter for low projection distances
tp-cli --gnss-file data.csv --gnss-crs EPSG:4326 --network-file network.geojson | \
awk -F',' 'NR==1 || $8 < 30' > high_quality_positions.csv
Problem: Forgot to specify --gnss-crs for CSV input.
Solution:
# Add --gnss-crs flag
tp-cli --gnss-file data.csv --gnss-crs EPSG:4326 --network-file network.geojson
Problem: Provided --gnss-crs with GeoJSON input (CRS read from file).
Solution:
# Remove --gnss-crs flag
tp-cli --gnss-file data.geojson --network-file network.geojson
Meaning: GNSS position is far from nearest track.
Possible causes:
Solutions:
--warning-threshold if distances are expectedProblem: Timestamps not in RFC3339 format or missing timezone.
Required format: YYYY-MM-DDTHH:MM:SS±HH:MM
Examples:
2025-12-09T14:30:00+01:00 (Brussels time)2025-12-09T13:30:00Z (UTC)2025-12-09 14:30:00 (missing T and timezone)2025-12-09T14:30:00 (missing timezone)Solution: Fix timestamps in input CSV to include timezone.
Problem: Netelement LineString has < 2 points or invalid coordinates.
Solution: Validate network GeoJSON:
[longitude, latitude] (not lat/lon)Symptom: Processing takes too long (> 10 seconds for 1000 positions × 50 netelements).
Possible causes:
Solutions:
# Process all CSV files in directory
for file in data/*.csv; do
echo "Processing $file..."
tp-cli --gnss-file "$file" \
--gnss-crs EPSG:4326 \
--network-file network.geojson \
> "output/$(basename $file .csv)_projected.csv"
done
# Convert output GeoJSON to Shapefile with ogr2ogr
tp-cli --gnss-file data.csv --gnss-crs EPSG:4326 --network-file network.geojson -o json | \
ogr2ogr -f "ESRI Shapefile" output.shp /vsistdin/ -lco ENCODING=UTF-8
# Extract only high-quality projections (< 20m distance)
tp-cli --gnss-file data.csv --gnss-crs EPSG:4326 --network-file network.geojson | \
awk -F',' 'NR==1 || ($8+0) < 20' > high_quality.csv
# View all options
tp-cli --help
# View version
tp-cli --version
For issues or questions: