From 82fecf95f6f1803cbff5acd172516b6d8897fc8e Mon Sep 17 00:00:00 2001 From: Henrik Fehlauer Date: Tue, 11 Jul 2023 17:57:14 +0000 Subject: [PATCH 1/2] Revert voice hint indexing change in JSON API to restore compatibility a9e8731 made voice hints available from `formatAsGeoJson()`, which is used both in the GeoJSON HTTP API and in the JSON Java API. To indicate a specific type of voice hint, it was chosen to include its numeric id in the output JSON array among other data. The full list of available ids was defined in `class VoiceHint`, e.g. `static final int C = 1;`. Consumers of the API now depended on the mapping from id to intended voice hint not changing, since otherwise incorrect voice hints could be displayed. Unfortunately that API contract was broken in c9ae7c8, where instead of assigning unused ids to new commands, the meaning of existing ids was changed. This broke compatibility: Clients adapted to the change did not work with the old indexing anymore, and clients not yet adapted would break with newer BRouter releases, e.g. they would suddenly display "Off route" for a "right u-turn". To restore compatibility, the indexing is reverted to its old state. This will unbreak GeoJSON/JSON API users no yet adapted to BRouter 1.7.0 or 1.7.1, e.g. BRouter-Web as well as unmaintained clients. While API users which already patched ids would need to undo or special-case their changes, the impact is believed to be low, as no such users are currently known and the breakage was released only recently. The changed meaning of `TU` in output formats (before: `u-turn-left`, now: `u-turn-180`) has not been reverted for now, since either that command is mapped to fallback solutions anyway (e.g. Orux, old Locus, Gpsies), the change has already been implemented in clients (new Locus, Cruiser) or was only planned to be implemented in the future (OsmAnd). Fixes #584 Test Plan: - `./gradlew test` - Run BRouter with an unpatched BRouter-Web and confirm voice hint ids have been restored to the same ones as emitted by BRouter 1.6.3. --- .../src/main/java/btools/router/VoiceHint.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/VoiceHint.java b/brouter-core/src/main/java/btools/router/VoiceHint.java index 5fea2d7a8..dd270c544 100644 --- a/brouter-core/src/main/java/btools/router/VoiceHint.java +++ b/brouter-core/src/main/java/btools/router/VoiceHint.java @@ -20,11 +20,11 @@ public class VoiceHint { static final int KL = 8; // keep left static final int KR = 9; // keep right static final int TLU = 10; // U-turn - static final int TU = 11; // 180 degree u-turn - static final int TRU = 12; // Right U-turn - static final int OFFR = 13; // Off route - static final int RNDB = 14; // Roundabout - static final int RNLB = 15; // Roundabout left + static final int TRU = 11; // Right U-turn + static final int OFFR = 12; // Off route + static final int RNDB = 13; // Roundabout + static final int RNLB = 14; // Roundabout left + static final int TU = 15; // 180 degree u-turn static final int BL = 16; // Beeline routing int ilon; From d98b1060d48dac056b39fcb423ec967c26792517 Mon Sep 17 00:00:00 2001 From: Henrik Fehlauer Date: Wed, 12 Jul 2023 08:59:12 +0000 Subject: [PATCH 2/2] Explicitly map internal voice hint ids to external JSON API ids As c9ae7c8 showed, changing internal ids without being aware of the possible impact might easily lead to break the external API. While ids could be fixated by adding respective tests, an even more elegant solution is to make the mapping from internal ids to external ids explicit, similar how it is already done for other voice hint formats. To underline the purpose of the mapping even more, the respective method is renamed appropriately. Test Plan: - `./gradlew test` - Export a complex route in BRouter-Web and check voice hints have not been changed. --- .../src/main/java/btools/router/OsmTrack.java | 2 +- .../main/java/btools/router/VoiceHint.java | 39 ++++++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/OsmTrack.java b/brouter-core/src/main/java/btools/router/OsmTrack.java index 89ffdacb3..8bb74d287 100644 --- a/brouter-core/src/main/java/btools/router/OsmTrack.java +++ b/brouter-core/src/main/java/btools/router/OsmTrack.java @@ -1000,7 +1000,7 @@ public String formatAsGeoJson() { for (VoiceHint hint : voiceHints.list) { sb.append(" ["); sb.append(hint.indexInTrack); - sb.append(',').append(hint.getCommand()); + sb.append(',').append(hint.getJsonCommandIndex()); sb.append(',').append(hint.getExitNumber()); sb.append(',').append(hint.distanceToNext); sb.append(',').append((int) hint.angle); diff --git a/brouter-core/src/main/java/btools/router/VoiceHint.java b/brouter-core/src/main/java/btools/router/VoiceHint.java index dd270c544..2f858beb0 100644 --- a/brouter-core/src/main/java/btools/router/VoiceHint.java +++ b/brouter-core/src/main/java/btools/router/VoiceHint.java @@ -61,8 +61,43 @@ public void addBadWay(MessageData badWay) { badWays.add(badWay); } - public int getCommand() { - return cmd; + public int getJsonCommandIndex() { + switch (cmd) { + case TLU: + return 10; + case TU: + return 15; + case TSHL: + return 4; + case TL: + return 2; + case TSLL: + return 3; + case KL: + return 8; + case C: + return 1; + case KR: + return 9; + case TSLR: + return 6; + case TR: + return 5; + case TSHR: + return 7; + case TRU: + return 11; + case RNDB: + return 13; + case RNLB: + return 14; + case BL: + return 16; + case OFFR: + return 12; + default: + throw new IllegalArgumentException("unknown command: " + cmd); + } } public int getExitNumber() {