Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial simple turn lane support #2954

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open

Initial simple turn lane support #2954

wants to merge 23 commits into from

Conversation

karussell
Copy link
Member

@karussell karussell commented Mar 22, 2024

Fixes #1131 and replaces #1269. These turn lane details help with the instructions to e.g. announce turns earlier.

Every instruction can contain multiple lane lists. For example one lane list 500m before the turn, then the lane list changes because the right turn was done (or the "right" and "through" lane separated) and then 200m before the turn there is another lane list.

Screenshot from a prototype client that can consume this data (turn_lanes branch).

image

Work to do:

@hactar
Copy link

hactar commented Mar 22, 2024

@karussell nice! I don't see any changes to https://github.com/graphhopper/graphhopper/tree/c64febe4522984a61b2d80dcf0d78135c19bfea5/navigation - am I correct to assume this will not improve the navigation module? If not, any plans to update that too? ☺️

@karussell
Copy link
Member Author

The /navigate endpoint uses the same instructions, so it will be changed too.

@hactar
Copy link

hactar commented Mar 22, 2024

Thanks for the info - I had assumed that the navigate endpoint would need some "conversion" so that it matches that format, glad to hear its in. I wish I could help review but alas Java has been a while - looking forward to seeing this in Graphhopper, and happy to test this against the Maplibre Navigation SDKs once its in and we can deploy it. Thanks for the PR!

@karussell
Copy link
Member Author

karussell commented Mar 22, 2024

Oh, yes, you are right it will need some modification in the converter! Maybe you can investigate the required format and contribute this change? Shouldn't be much I guess even without much Java knowledge :)

@hactar
Copy link

hactar commented Mar 22, 2024

I'd need to set up the whole toolchain, best someone else tackles this 😅. I'll reach out to our backend team and see if they can help. For now at least linking some documentation. While this is documentation for the newest API version, I quickly checked and it appears to still match the older format used by MapLibre Navigation SDK:

https://docs.mapbox.com/api/navigation/directions/#lane-object

Some sample code of a route step containing lane info:

{
  "intersections": [
    {
      "out": 1,
      "location": [13.424671, 52.508812],
      "bearings": [120, 210, 300],
      "entry": [false, true, true],
      "in": 0,
      "stop_sign": true,
      "lanes": [
        {
          "valid": true,
          "active": true,
          "valid_indication": "straight",
          "indications": ["left", "straight"]
        },
        {
          "valid": true,
          "active": false,
          "valid_indication": "straight",
          "indications": ["straight", "right"]
        },
        {
          "valid": false,
          "active": false,
          "indications": ["right"]
        }
      ]
    }
  ],
  "geometry": "asn_Ie_}pAdKxG",
  "maneuver": {
    "bearing_after": 202,
    "type": "turn",
    "modifier": "left",
    "bearing_before": 299,
    "location": [13.424671, 52.508812],
    "instruction": "Turn left onto Adalbertstraße"
  },
  "duration": 59.1,
  "distance": 236.9,
  "driving_side": "right",
  "weight": 59.1,
  "name": "Adalbertstraße",
  "mode": "driving"
}

@karussell
Copy link
Member Author

I'm unsure if these are the necessary objects. Because there is another place for the sub component if components.type=lane, which looks more suitable for the per-instruction ("per-maneuver") information and not per-junction:

JSON

 "sub": {
    "text": "",
    "components": [
      {
        "text": "",
        "type": "lane",
        "directions": ["left"],
        "active": true
      },
      {
        "text": "",
        "type": "lane",
        "directions": ["left", "straight"],
        "active": true
      },
      {
        "text": "",
        "type": "lane",
        "directions": ["right"],
        "active": false
      }
    ]
  }

But it is unclear to me, where the distance of the lane info (before the turn) is specified. Because for the client side this is important to always show the current lane and this could change multiple times per turn.

So I'd prefer if someone else steps in for the /navigate endpoint, who can also check if the format changes are picked up properly on the client side.

@hactar
Copy link

hactar commented Mar 22, 2024

You're right, there's more to it. I went through the iOS navigation code, and the mentioned lane info for banners comes from where you say it does (https://github.com/flitsmeister/mapbox-directions-swift/blob/6c19ecc4e1324887ae3250802b8d13d8d8b3ff2d/MapboxDirections/MBVisualInstruction.swift#L73)

Here's a test file from the MapLibre Navigation iOS SDK, it contains lane info on both the level that I described but also at the level you described - should show how it should look like.

https://github.com/maplibre/maplibre-navigation-ios/blob/main/MapboxCoreNavigationTests/A12-To-Veenendaal-Bigger-Detour.json

@IAbderrahmane
Copy link

hi @karussell, I want to add lane support to the /navigate response. I'll start with adding it to the bannerInstructions but I have some questions:

  1. Instruction.instructionDetails is an array, if the size is one I can just add the lane information to the current bannerInstruction but what if it contains more than one element ? let's say we have to InstructionDetails and both of them contain lane information. Do I create 2 bannerInstructions ? they both contain the same primary attribute but different sub attributes. the first one is the closest lane information (based on beforeTurn maybe ?) and the second one is the farthest.
  2. in the MapBox spec there's an additional field active_direction here's the definition: When components.active is true, this property shows which of the lane's components.directions applies to the current route, when there is more than one . Where should I put this information ? I found to possible locations one is LaneInfo class the other one is NavigateResponseConverter.putSingleBannerInstruction. I'm leaning towards the second one since it's needed only in the navigate endpoint.

@karussell
Copy link
Member Author

karussell commented Apr 24, 2024

I want to add lane support to the /navigate response.

Great, that's much appreciated!

Do I create 2 bannerInstructions ?

I don't know. But there should be a way to specify multiple InstructionDetails instances for every turn. Imagine there is a left turn and initially you have two lanes (left|through and right) but a few meters further it are three lanes (left|through|right) and so there must be a way to specify multiple InstructionDetails per turn instruction.

Could it be that there are multiple banner instruction objects per turn? Because the "distanceAlongGeometry" is per banner instruction object and this seems to be related to our InstructionDetails.beforeTurn.

I'm leaning towards the second one since it's needed only in the navigate endpoint.

Yes, sounds good. At the moment we only have "valid".

@karussell karussell added this to the 10.0 milestone Apr 24, 2024
* added lanes support to navigate endpoint

* added tests for turn lane support in navigate endpoint
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Instructions: parse turn:lanes to improve instructions
3 participants