Skip to content

fix: Nearest API returning node ID 0 at start of one-way road#7427

Merged
DennisOSRM merged 2 commits intomasterfrom
fix/7047-nearest-node-id-zero
Mar 24, 2026
Merged

fix: Nearest API returning node ID 0 at start of one-way road#7427
DennisOSRM merged 2 commits intomasterfrom
fix/7047-nearest-node-id-zero

Conversation

@DennisOSRM
Copy link
Copy Markdown
Collaborator

Summary

Fixes #7047 — the Nearest API was returning nodes[0] = 0 when a queried location snaps to the very beginning of a one-way road segment (fwd_segment_position == 0). In that case, neither the reverse_segment branch nor the fwd_segment_position > 0 branch applied, leaving from_node uninitialised (zero).

Supersedes #7048 — this PR is a clean rebase of that work onto current master, with all code review feedback addressed.

Changes

  • include/engine/api/nearest_api.hpp: Add explicit else if (fwd_segment_position == 0) branch that swaps from_node = to_node and sets to_node to the next node, so the edge runs forward (a → x) instead of returning a zero ID. Adds BOOST_ASSERT(forward_geometry.size() >= 2) guard.
  • features/nearest/nodes.feature: New cucumber scenario that reproduces the bug (one-way road, query at start node) and verifies both node IDs are valid and non-zero.
  • features/step_definitions/nearest.js: Extend nearest step definitions to support a nodes column for verifying waypoints[0].nodes in test tables.
  • CHANGELOG.md: Updated.

Co-authorship

The original fix was proposed by @muteebali in #7048. This PR incorporates that work with the formatting and structural improvements requested during code review.

When a location snaps to the beginning of a one-way forward segment
(fwd_segment_position == 0), the from_node was left as 0 because neither
the reverse_segment branch nor the fwd_segment_position > 0 branch applied.

Fix: add an explicit else-if for fwd_segment_position == 0 that swaps
from/to so the edge runs forward (a → x) instead of returning a zero ID.

Addresses code review comments from PR #7048:
- Restructured as a separate top-level else-if (per @afarber suggestion)
- Added BOOST_ASSERT(forward_geometry.size() >= 2) guard
- Added cucumber test verifying non-zero node IDs on a one-way road snap
- Updated CHANGELOG

Co-authored-by: Muteeb Ali <31405887+muteebali@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes an edge-case in the Nearest API where snapping to the very start of a one-way segment could return an uninitialized from_node (serialized as node ID 0) by ensuring a valid (from,to) node pair is always produced, and adds a regression test for it.

Changes:

  • Fix NearestAPI::MakeNodes to handle fwd_segment_position == 0 on one-way forward geometry by returning the first two geometry nodes (a → x) instead of leaving from_node as 0.
  • Add a cucumber regression scenario covering “snap at start of one-way” and verifying waypoint node IDs.
  • Extend nearest cucumber step definitions to validate waypoints[0].nodes via a nodes table column.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
include/engine/api/nearest_api.hpp Adds explicit handling for fwd_segment_position == 0 to avoid returning nodes[0] = 0 on one-way segments.
features/step_definitions/nearest.js Adds support for asserting the nodes array in Nearest API responses from cucumber tables.
features/nearest/nodes.feature New regression test scenario reproducing the one-way start snap bug and asserting returned node IDs.
CHANGELOG.md Documents the Nearest API bugfix under Unreleased routing fixes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +49 to +54
} else if (key === 'nodes') {
const nodeNames = row.nodes.split(',').map(n => n.trim());
const fromNode = this.findNodeByName(nodeNames[0]);
const toNode = this.findNodeByName(nodeNames[1]);
if (!fromNode) throw new Error(util.format('*** unknown from-node "%s"', nodeNames[0]));
if (!toNode) throw new Error(util.format('*** unknown to-node "%s"', nodeNames[1]));
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

The nodes column parsing assumes row.nodes always contains exactly two comma-separated node names. If the value is missing a comma (or has extra entries), nodeNames[1] becomes undefined and findNodeByName(undefined) will throw a generic TypeError (accessing .length) or silently ignore additional nodes. Consider validating that the split yields exactly 2 non-empty names and throwing a clearer error (e.g. nodes must be from,to).

Copilot uses AI. Check for mistakes.
Validate that the nodes column contains exactly two comma-separated,
non-empty node names before calling findNodeByName, giving a clear
error message instead of a cryptic TypeError on malformed input.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@DennisOSRM DennisOSRM enabled auto-merge (squash) March 24, 2026 12:16
@DennisOSRM DennisOSRM disabled auto-merge March 24, 2026 13:02
@DennisOSRM DennisOSRM merged commit c3dc148 into master Mar 24, 2026
23 checks passed
@DennisOSRM DennisOSRM deleted the fix/7047-nearest-node-id-zero branch March 24, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Nearest api returning node with id 0

2 participants