From c4eff6cd656b49e3cb5fc841e868031e12a97465 Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Thu, 19 Apr 2018 10:08:15 +0000 Subject: [PATCH 1/5] Add option to osrm-runner to limit the distance --- scripts/osrm-runner.js | 61 +++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/scripts/osrm-runner.js b/scripts/osrm-runner.js index ea3ce8e89..c424d8faf 100755 --- a/scripts/osrm-runner.js +++ b/scripts/osrm-runner.js @@ -36,27 +36,51 @@ const run_query = (query_options, filters, callback) => { }).end(); }; -function generate_points(polygon, number) { +function generate_points(polygon, number, coordinates_number, max_distance) { let query_points = []; while (query_points.length < number) { - var chunk = turf - .random('points', number, { bbox: turf.bbox(polygon)}) - .features - .map(x => x.geometry.coordinates) - .filter(pt => turf.inside(pt, polygon)); - query_points = query_points.concat(chunk); + let points = []; + + while(points.length < coordinates_number) { + let chunk = turf + .random('points', coordinates_number, { bbox: turf.bbox(polygon)}) + .features + .map(x => x.geometry.coordinates) + .filter(pt => turf.inside(pt, polygon)); + + if (max_distance > 0) + { + chunk.forEach(pt => { + if (points.length == 0) + { + points.push(pt); + } + else + { + let distance = turf.distance(pt, points[points.length-1], 'meters'); + if (distance < max_distance) + { + points.push(pt); + } + } + }); + } + else + { + points = points.concat(chunk); + } + } + + query_points.push(points); } - return query_points.slice(0, number); + + return query_points; } -function generate_queries(options, query_points, coordinates_number) { - let queries = []; - for (let chunk = 0; chunk < query_points.length; chunk += coordinates_number) - { - let points = query_points.slice(chunk, chunk + coordinates_number); - let query = options.path.replace(/{}/g, x => points.pop().join(',')); - queries.push(query); - } +function generate_queries(options, query_points) { + let queries = query_points.map(points => { + return options.path.replace(/{}/g, x => points.pop().join(',')); + }); return queries; } @@ -80,6 +104,7 @@ const optionsList = [ {name: 'bounding-box', alias: 'b', type: BoundingBox, defaultValue: BoundingBox('5.86442,47.2654,15.0508,55.1478'), multiple: true, description: 'queries bounding box, default "5.86442,47.2654,15.0508,55.1478"', typeLabel: '{underline west,south,east,north}'}, {name: 'max-sockets', alias: 'm', type: Number, defaultValue: 1, description: 'how many concurrent sockets the agent can have open per origin, default 1', typeLabel: '{underline number}'}, {name: 'number', alias: 'n', type: Number, defaultValue: 10, description: 'number of query points, default 10', typeLabel: '{underline number}'}, + {name: 'max-distance', alias: 'd', type: Number, defaultValue: -1, description: 'maximal distance between coordinates', typeLabel: '{underline number}'}, {name: 'queries-files', alias: 'q', type: String, description: 'CSV file with queries in the first row', typeLabel: '{underline file}'}, ]; const options = cla(optionsList); @@ -109,8 +134,8 @@ if (options.hasOwnProperty('queries-files')) { } else { const polygon = options['bounding-box'].map(x => x.poly).reduce((x,y) => turf.union(x, y)); const coordinates_number = (options.path.match(/{}/g) || []).length; - const query_points = generate_points(polygon, coordinates_number * options.number); - queries = generate_queries(options, query_points, coordinates_number); + const query_points = generate_points(polygon, options.number, coordinates_number, options['max-distance']); + queries = generate_queries(options, query_points); } queries = queries.map(q => { return {hostname: options.server.hostname, port: options.server.port, path: q}; }); From 7740d5d7c0f50692fdd03171f34b9e123d5d71dd Mon Sep 17 00:00:00 2001 From: Duane Gearhart Date: Fri, 20 Apr 2018 05:41:53 -0400 Subject: [PATCH 2/5] Do not combine a segregated edge with a roundabout (#5040) * Do not combine a segregated edge with a roundabout, add test --- CHANGELOG.md | 5 ++ features/testbot/fixed.feature | 63 +++++++++++++++++++++++++- scripts/osm2cucumber.js | 43 ++++++++++++++++++ src/engine/guidance/collapse_turns.cpp | 7 +-- 4 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 scripts/osm2cucumber.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 603f540c6..424a6312c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 5.17.1 + - Changes from 5.17.0: + - Bugfixes: + - FIXED: Do not combine a segregated edge with a roundabout [#5039](https://github.com/Project-OSRM/osrm-backend/issues/5039) + # 5.17.0 - Changes from 5.16.0: - Bugfixes: diff --git a/features/testbot/fixed.feature b/features/testbot/fixed.feature index 9d83649ff..1eb66b89f 100644 --- a/features/testbot/fixed.feature +++ b/features/testbot/fixed.feature @@ -39,5 +39,64 @@ Feature: Fixed bugs, kept to check for regressions | de | yes | When I route I should get - | from | to | route | - | 1 | 2 | bcd,bcd | + | from | to | route | + | 1 | 2 | bcd,bcd | + + ############################# + # This test models the OSM map at the location for + # https://github.com/Project-OSRM/osrm-backend/issues/5039 + ############################# + Scenario: Mixed Entry and Exit and segregated + Given the profile file "car" initialized with + """ + profile.properties.left_hand_driving = true + """ + Given the node locations + | node | lon | lat | + | a | 171.12889297029 | -42.58425289548 | + | b | 171.1299357 | -42.5849295 | + | c | 171.1295427 | -42.5849385 | + | d | 171.1297356 | -42.5852029 | + | e | 171.1296909 | -42.5851986 | + | f | 171.1295097 | -42.585007 | + | g | 171.1298225 | -42.5851928 | + | h | 171.1300262 | -42.5859122 | + | i | 171.1292651 | -42.584698 | + | j | 171.1297209 | -42.5848569 | + | k | 171.1297188 | -42.5854056 | + | l | 171.1298326 | -42.5857266 | + | m | 171.1298871 | -42.5848922 | + | n | 171.1296505 | -42.585189 | + | o | 171.1295206 | -42.5850862 | + | p | 171.1296106 | -42.5848862 | + | q | 171.1299784 | -42.5850191 | + | r | 171.1298867 | -42.5851671 | + | s | 171.1306955 | -42.5845812 | + | t | 171.129525 | -42.584807 | + | u | 171.1299705 | -42.584984 | + | v | 171.1299067 | -42.5849073 | + | w | 171.1302061 | -42.5848173 | + | x | 171.12975 | -42.5855753 | + | y | 171.129969 | -42.585079 | + | 1 | 171.131511926651| -42.584306746421966 | + | 2 | 171.128743886947| -42.58414875714669 | + And the ways + | nodes | highway | maxspeed | name | ref | surface | junction | oneway | + | ws | primary | 100 | Taramakau Highway | SH 6 | asphalt | | | + | kxlh | trunk | | Otira Highway | SH 73 | | | | + | ai | primary | 100 | Kumara Junction Highway | SH 6 | asphalt | | | + | qyrgdenof | primary | 100 | Kumara Junction | | | roundabout | yes | + | ke | trunk | | Otira Highway | SH 73 | | | yes | + | itj | primary | 100 | Kumara Junction Highway | SH 6 | | | yes | + | gk | trunk | | Otira Highway | SH 73 | | | yes | + | fi | primary | 100 | Kumara Junction Highway | SH 6 | | | yes | + | wq | primary | 100 | Taramakau Highway | SH 6 | | | yes | + | vw | primary | 100 | Taramakau Highway | SH 6 | | | yes | + | vbuq | primary | 100 | Kumara Junction | | | roundabout | yes | + | jmv | primary | 100 | Kumara Junction | | | roundabout | yes | + | fcpj | primary | 100 | Kumara Junction | | | roundabout | yes | + + When I route I should get + | waypoints | route | turns | + | 1,2 | Taramakau Highway,Kumara Junction Highway,Kumara Junction Highway,Kumara Junction Highway | depart,Kumara Junction-exit-2,exit rotary slight left,arrive | + diff --git a/scripts/osm2cucumber.js b/scripts/osm2cucumber.js new file mode 100644 index 000000000..d123c6fe6 --- /dev/null +++ b/scripts/osm2cucumber.js @@ -0,0 +1,43 @@ +/********************************* + * Takes an XML `.osm` file and converts it into a cucumber scenario definition like + * Given the node locations + * | node | lon | lat | + * ..... + * Given the ways + * | nodes | tag1 | tag2 | tag3 | + * ..... + * + * Note that cucumber tests are limited to 26 nodes (labelled a-z), so + * you'll need to use pretty small OSM extracts to get this to work. + *****************************************/ +var fs = require('fs'); +var parseString = require('xml2js').parseString; + +var data = fs.readFileSync('filename.osm', 'utf8'); + +const items = parseString(data, (err, result) => { +var idmap = {}; + +console.log('Given the node locations'); +console.log(' | node | lon | lat |'); +result.osm.node.filter(n => !n.$.action || n.$.action !== 'delete').forEach(i => { + var code = String.fromCharCode(97 + Object.keys(idmap).length) + idmap[i.$.id] = code; + console.log(` | ${code} | ${i.$.lon} | ${i.$.lat} |`); +}); + +var allkeys = {}; +var waytags = {}; + +result.osm.way.filter(n => !n.$.action || n.$.action !== 'delete').forEach(w => { + if (!waytags[w.$.id]) waytags[w.$.id] = {}; + w.tag.forEach(t => { allkeys[t.$.k] = t.$.v; waytags[w.$.id][t.$.k] = t.$.v; }); +}); + +console.log('And the ways'); +console.log(` | nodes | ${Object.keys(allkeys).join(' | ')} |`); + +result.osm.way.filter(n => !n.$.action || n.$.action !== 'delete').forEach(w => { + console.log(` | ${w.nd.map(n => idmap[n.$.ref]).join('')} | ${Object.keys(allkeys).map(k => waytags[w.$.id][k] || '').join(' | ')} |`); +}); +}); diff --git a/src/engine/guidance/collapse_turns.cpp b/src/engine/guidance/collapse_turns.cpp index be3680827..8bf6570d7 100644 --- a/src/engine/guidance/collapse_turns.cpp +++ b/src/engine/guidance/collapse_turns.cpp @@ -618,9 +618,10 @@ RouteSteps collapseSegregatedTurnInstructions(RouteSteps steps) TransferLanesStrategy()); ++next_step; } - // else if the current step is segregated and the next step is not then combine with turn - // adjustment - else if (curr_step->is_segregated && !next_step->is_segregated) + // else if the current step is segregated and the next step is not segregated + // and the next step is not a roundabout then combine with turn adjustment + else if (curr_step->is_segregated && !next_step->is_segregated && + !hasRoundaboutType(next_step->maneuver.instruction)) { // Determine if u-turn if (bearingsAreReversed( From 35973576d901c66342bfe6bc7689d739ca1c0b3f Mon Sep 17 00:00:00 2001 From: Karen Shea Date: Fri, 20 Apr 2018 13:19:06 +0200 Subject: [PATCH 3/5] Update releasing.md --- docs/releasing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/releasing.md b/docs/releasing.md index efe78ddde..1fe032f67 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -43,9 +43,9 @@ We may introduce forward-compatible changes: query parameters and response prope 1. Check out the appropriate release branch `x.y` 2. Make sure `CHANGELOG.md` is up to date. -3. Make sure the `package.json` is up to date. +3. Make sure the `package.json` on branch `x.y` has been committed. 4. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:) -5. Use an annotated tag to mark the release: `git tag vx.y.z -a` Body of the tag description should be the changelog entries. +5. Use an annotated tag to mark the release: `git tag vx.y.z -a` Body of the tag description should be the changelog entries. Commit should be one in which the `package.json` version matches the version you want to release. 6. Use `npm run docs` to generate the API documentation. Copy `build/docs/*` to `https://github.com/Project-OSRM/project-osrm.github.com` in the `docs/vN.N.N/api` directory 7. Push tags and commits: `git push; git push --tags` 8. On https://github.com/Project-OSRM/osrm-backend/releases press `Draft a new release`, From 8085e86170d281403520efd643ef63ea36bfa98c Mon Sep 17 00:00:00 2001 From: Karen Shea Date: Fri, 20 Apr 2018 13:19:48 +0200 Subject: [PATCH 4/5] Change emoji --- docs/releasing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/releasing.md b/docs/releasing.md index 1fe032f67..9a492cd49 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -44,7 +44,7 @@ We may introduce forward-compatible changes: query parameters and response prope 1. Check out the appropriate release branch `x.y` 2. Make sure `CHANGELOG.md` is up to date. 3. Make sure the `package.json` on branch `x.y` has been committed. -4. Make sure all tests are passing (e.g. Travis CI gives you a :thumbs_up:) +4. Make sure all tests are passing (e.g. Travis CI gives you a :green_apple:) 5. Use an annotated tag to mark the release: `git tag vx.y.z -a` Body of the tag description should be the changelog entries. Commit should be one in which the `package.json` version matches the version you want to release. 6. Use `npm run docs` to generate the API documentation. Copy `build/docs/*` to `https://github.com/Project-OSRM/project-osrm.github.com` in the `docs/vN.N.N/api` directory 7. Push tags and commits: `git push; git push --tags` From 6f84812903f8a316895df86e71f8e031256df51f Mon Sep 17 00:00:00 2001 From: Antoine Giret Date: Fri, 20 Apr 2018 09:51:16 +0200 Subject: [PATCH 5/5] Update profiles.md --- docs/profiles.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/profiles.md b/docs/profiles.md index 49beff303..248e9cb52 100644 --- a/docs/profiles.md +++ b/docs/profiles.md @@ -224,8 +224,8 @@ source_highway_turn_classification | Read | Integer | source_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)) source_speed | Read | Integer | Speed on this source road in km/h source_priority_class | Read | Enum | The type of road priority class of the source. Defined in `include/extractor/guidance/road_classification.hpp` -target_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`) -target_mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp` +target_restricted | Read | Boolean | Is the target a restricted access road? (See definition in `process_way`) +target_mode | Read | Enum | Travel mode after the turn. Defined in `include/extractor/travel_mode.hpp` target_is_motorway | Read | Boolean | Is the target road a motorway? target_is_link | Read | Boolean | Is the target road a link? target_number_of_lanes | Read | Integer | How many lanes does the target road have? (default when not tagged: 0)