Skip to content

core, editoast: add topological to geometric offset projection on /path endpoint - #17476

Open
neigeantre wants to merge 2 commits into
devfrom
abo/core-editoast/topologic-to-geometric-projection
Open

neigeantre wants to merge 2 commits into
devfrom
abo/core-editoast/topologic-to-geometric-projection

Conversation

@neigeantre

@neigeantre neigeantre commented Jul 1, 2026 •

Copy link
Copy Markdown
Contributor
  • Change TrainPath interface in core to access the path's partial track sections
  • Add property geom_projection to core and editoast APIs
  • Test the computing of geom_projection in core

fix #9372

Important

The length computed in core for the LineString geometry is not exact, so it differs from the one we compute in the front (which is exact, using @turf/length package, implementing Haversine formula).

So we decided to implement the same formula in core, only for the loading of the infra, and being careful as to where we also have to make corresponding changes.

@neigeantre neigeantre self-assigned this Jul 1, 2026
@neigeantre
neigeantre requested review from a team as code owners July 1, 2026 12:53
@neigeantre
neigeantre requested a review from Khoyo July 1, 2026 12:53
@github-actions github-actions Bot added area:core Work on Core Service area:front Work on Standard OSRD Interface modules area:editoast Work on Editoast Service kind:api-change labels Jul 1, 2026
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ API changes

This Pull Request introduces some changes in the API:

  • please own it: notify or even prepare dedicated PR(s) to consumer projects

Comment thread editoast/core_client/src/path_properties.rs
Comment thread editoast/core_client/src/path_properties.rs
@neigeantre
neigeantre force-pushed the abo/core-editoast/topologic-to-geometric-projection branch from 9ee4581 to 1ce4952 Compare July 1, 2026 13:19
@neigeantre
neigeantre requested a review from a team as a code owner July 1, 2026 13:19
@neigeantre
neigeantre force-pushed the abo/core-editoast/topologic-to-geometric-projection branch from 1ce4952 to 5400d80 Compare July 1, 2026 14:26
@github-actions github-actions Bot added the area:integration-tests Work on Integration test, by nature related to different services label Jul 1, 2026
@neigeantre
neigeantre force-pushed the abo/core-editoast/topologic-to-geometric-projection branch 3 times, most recently from 8f804c0 to 904e545 Compare July 2, 2026 12:30

@bougue-pe bougue-pe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 LTGM overall, thanks for the tests.
Only comments on the form.

Comment thread core/src/main/kotlin/fr/sncf/osrd/api/path_properties/PathPropResponse.kt Outdated
Comment thread core/src/test/kotlin/fr/sncf/osrd/pathfinding/PathPropEndpointTest.kt Outdated
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
#[schema(as = CorePropertyGeometryProjection)]
pub struct GeometryProjection {
/// Topologic offsets in millimeters.

@bougue-pe bougue-pe Jul 3, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the en-US word is topological.
Ditto for all this PR (code + commits + github).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in the code, will do it in commit messages when I rebase

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I let you do a ctrl+F topologic but spotted leftovers in code, PR title, etc.
Anyway, this comment is a reminder for what's left, currently, so letting this open.

Comment thread editoast/core_client/src/path_properties.rs Outdated
@neigeantre
neigeantre marked this pull request as draft July 10, 2026 13:25
…_properties endpoint

- Change `TrainPath` interface in core to access the path's partial track sections
- Add property `geom_projection` to core and editoast APIs
- Test the computing of `geom_projection` in core

Signed-off-by: Arthur Bougeard <covillesheer@gmail.com>
@neigeantre
neigeantre force-pushed the abo/core-editoast/topologic-to-geometric-projection branch from 5cac885 to a9c04c1 Compare September 21, 2026 12:37
@neigeantre neigeantre changed the title core, editoast: add topologic to geometric offset projection on /path endpoint [WIP] core, editoast: add topologic to geometric offset projection on /path endpoint Sep 21, 2026

@bougue-pe bougue-pe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waiting for the switch to haversine, but it looks good so far :)


data class GeometricProjection(
@Json(name = "topo_offsets") val topoOffsets: List<Offset<PhysicsPath>>,
@Json(name = "geom_offsets") val geomOffsets: List<Offset<RJSLineString>>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's about to become RJSMutliLineString 😅

I'd say the first one merged wins (but notify the other to propagate the change)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for this, I’ll be watching if that PR is merged before this one

Comment on lines +70 to +72
for (i in 0..<(topoOffsets.size - 1)) {
assert(topoOffsets[i] <= topoOffsets[i + 1])
assert(geomOffsets[i] <= geomOffsets[i + 1])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: It would be nicer to trigger the loop only inside asserts (spare the loop if assert is not triggered).

I'd probably go using .zipWithNext() and .all{} to do that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +175 to +181
val rangeTopoLength = range.length
val trackSectionTopoLength = range.objectLength
val trackSectionGeomLength = getTrackSectionGeometricLength(range.value.value)
topoOffsets.addLast(topoOffsets.last() + rangeTopoLength)
val proportion = rangeTopoLength / trackSectionTopoLength.distance
val rangeGeomLength = trackSectionGeomLength.distance * proportion
geomOffsets.addLast(geomOffsets.last() + rangeGeomLength)

@bougue-pe bougue-pe Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it would be easier to read if "stories" have as little overlap as possible (just reordering below).

Suggested change
val rangeTopoLength = range.length
val trackSectionTopoLength = range.objectLength
val trackSectionGeomLength = getTrackSectionGeometricLength(range.value.value)
topoOffsets.addLast(topoOffsets.last() + rangeTopoLength)
val proportion = rangeTopoLength / trackSectionTopoLength.distance
val rangeGeomLength = trackSectionGeomLength.distance * proportion
geomOffsets.addLast(geomOffsets.last() + rangeGeomLength)
val rangeTopoLength = range.length
topoOffsets.addLast(topoOffsets.last() + rangeTopoLength)
val trackSectionTopoLength = range.objectLength
val proportion = rangeTopoLength / trackSectionTopoLength.distance
val trackSectionGeomLength = getTrackSectionGeometricLength(range.value.value)
val rangeGeomLength = trackSectionGeomLength.distance * proportion
geomOffsets.addLast(geomOffsets.last() + rangeGeomLength)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +95 to +96
val firstTrackRangeLength = (firstTrackRangeProportion * trackTA0GeoLength).toLong()
val secondTrackRangeLength = trackTA1GeoLength.toLong()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like you can avoid * 1000 and .toLong() using Double.meters to get a Distance.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this part

val chunks = rawInfra.getTrackSectionChunks(trackSection)
return chunks
.map {
Length<RJSLineString>(Distance.fromMeters(rawInfra.getTrackChunkGeom(it).length))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: shorter

Suggested change
Length<RJSLineString>(Distance.fromMeters(rawInfra.getTrackChunkGeom(it).length))
Length<RJSLineString>(rawInfra.getTrackChunkGeom(it).length.meters)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@neigeantre neigeantre changed the title [WIP] core, editoast: add topologic to geometric offset projection on /path endpoint [WIP] core, editoast: add topological to geometric offset projection on /path endpoint Sep 24, 2026
@neigeantre
neigeantre force-pushed the abo/core-editoast/topologic-to-geometric-projection branch from b27f512 to b31a832 Compare September 25, 2026 08:54
@neigeantre
neigeantre added this pull request to stack #18780 September 25, 2026 13:17
@neigeantre neigeantre changed the title [WIP] core, editoast: add topological to geometric offset projection on /path endpoint core, editoast: add topological to geometric offset projection on /path endpoint Sep 25, 2026
@neigeantre
neigeantre marked this pull request as ready for review September 25, 2026 14:03

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core Work on Core Service area:editoast Work on Editoast Service area:front Work on Standard OSRD Interface modules area:integration-tests Work on Integration test, by nature related to different services kind:api-change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

general issue: path data APIs aren't robust to coordinate errors

3 participants