Merge branch 'master' into sf-restriction-parser
This commit is contained in:
commit
94495b50a8
58
.github/workflows/osrm-backend.yml
vendored
58
.github/workflows/osrm-backend.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
continue-on-error: false
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: pip install conan==1.50.0
|
||||
- run: pip install conan==1.51.3
|
||||
- run: conan --version
|
||||
- run: cmake --version
|
||||
- uses: actions/setup-node@v3
|
||||
@ -138,7 +138,8 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TOOLS: ON
|
||||
BUILD_TYPE: Debug
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
CUCUMBER_TIMEOUT: 60000
|
||||
|
||||
- name: clang-11.0-debug-clang-tidy
|
||||
@ -147,7 +148,8 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TOOLS: ON
|
||||
BUILD_TYPE: Debug
|
||||
CLANG_VERSION: 11.0.0
|
||||
CCOMPILER: clang-11
|
||||
CXXCOMPILER: clang++-11
|
||||
CUCUMBER_TIMEOUT: 60000
|
||||
ENABLE_CLANG_TIDY: ON
|
||||
|
||||
@ -157,7 +159,8 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TOOLS: ON
|
||||
BUILD_TYPE: Release
|
||||
CLANG_VERSION: 11.0.0
|
||||
CCOMPILER: clang-11
|
||||
CXXCOMPILER: clang++-11
|
||||
ENABLE_CONAN: ON
|
||||
ENABLE_SANITIZER: ON
|
||||
|
||||
@ -167,7 +170,8 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TOOLS: ON
|
||||
BUILD_TYPE: Release
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_CONAN: ON
|
||||
|
||||
- name: gcc-11-release
|
||||
@ -285,7 +289,8 @@ jobs:
|
||||
node: 12
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TYPE: Release
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_GLIBC_WORKAROUND: ON
|
||||
ENABLE_CONAN: ON
|
||||
NODE_PACKAGE_TESTS_ONLY: ON
|
||||
@ -296,7 +301,8 @@ jobs:
|
||||
node: 12
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TYPE: Debug
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_GLIBC_WORKAROUND: ON
|
||||
ENABLE_CONAN: ON
|
||||
NODE_PACKAGE_TESTS_ONLY: ON
|
||||
@ -307,7 +313,8 @@ jobs:
|
||||
node: 14
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TYPE: Release
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_GLIBC_WORKAROUND: ON
|
||||
ENABLE_CONAN: ON
|
||||
NODE_PACKAGE_TESTS_ONLY: ON
|
||||
@ -318,7 +325,8 @@ jobs:
|
||||
node: 14
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TYPE: Debug
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_GLIBC_WORKAROUND: ON
|
||||
ENABLE_CONAN: ON
|
||||
NODE_PACKAGE_TESTS_ONLY: ON
|
||||
@ -330,7 +338,8 @@ jobs:
|
||||
node: 16
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TYPE: Release
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_GLIBC_WORKAROUND: ON
|
||||
ENABLE_CONAN: ON
|
||||
NODE_PACKAGE_TESTS_ONLY: ON
|
||||
@ -341,7 +350,8 @@ jobs:
|
||||
node: 16
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TYPE: Debug
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_GLIBC_WORKAROUND: ON
|
||||
ENABLE_CONAN: ON
|
||||
NODE_PACKAGE_TESTS_ONLY: ON
|
||||
@ -364,7 +374,8 @@ jobs:
|
||||
node: latest
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TYPE: Release
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_GLIBC_WORKAROUND: ON
|
||||
ENABLE_CONAN: ON
|
||||
NODE_PACKAGE_TESTS_ONLY: ON
|
||||
@ -375,7 +386,8 @@ jobs:
|
||||
node: latest
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TYPE: Debug
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_GLIBC_WORKAROUND: ON
|
||||
ENABLE_CONAN: ON
|
||||
NODE_PACKAGE_TESTS_ONLY: ON
|
||||
@ -398,7 +410,8 @@ jobs:
|
||||
node: "lts/*"
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TYPE: Release
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_GLIBC_WORKAROUND: ON
|
||||
ENABLE_CONAN: ON
|
||||
NODE_PACKAGE_TESTS_ONLY: ON
|
||||
@ -409,7 +422,8 @@ jobs:
|
||||
node: "lts/*"
|
||||
runs-on: ubuntu-20.04
|
||||
BUILD_TYPE: Debug
|
||||
CLANG_VERSION: 6.0.0
|
||||
CCOMPILER: clang-6.0
|
||||
CXXCOMPILER: clang++-6.0
|
||||
ENABLE_GLIBC_WORKAROUND: ON
|
||||
ENABLE_CONAN: ON
|
||||
NODE_PACKAGE_TESTS_ONLY: ON
|
||||
@ -423,7 +437,6 @@ jobs:
|
||||
BUILD_SHARED_LIBS: ${{ matrix.BUILD_SHARED_LIBS }}
|
||||
CCOMPILER: ${{ matrix.CCOMPILER }}
|
||||
CFLAGS: ${{ matrix.CFLAGS }}
|
||||
CLANG_VERSION: ${{ matrix.CLANG_VERSION }}
|
||||
CUCUMBER_TIMEOUT: ${{ matrix.CUCUMBER_TIMEOUT }}
|
||||
CXXCOMPILER: ${{ matrix.CXXCOMPILER }}
|
||||
CXXFLAGS: ${{ matrix.CXXFLAGS }}
|
||||
@ -515,26 +528,23 @@ jobs:
|
||||
echo "$(${MASON} prefix ccache ${CCACHE_VERSION})/bin" >> $GITHUB_PATH
|
||||
|
||||
# clang
|
||||
if [[ -n ${CLANG_VERSION} ]]; then
|
||||
echo "CCOMPILER=clang" >> $GITHUB_ENV
|
||||
echo "CXXCOMPILER=clang++" >> $GITHUB_ENV
|
||||
${MASON} install clang++ ${CLANG_VERSION}
|
||||
echo "$(${MASON} prefix clang++ ${CLANG_VERSION})/bin" >> $GITHUB_PATH
|
||||
if [[ "${CCOMPILER}" == "clang-6.0" ]]; then
|
||||
sudo apt-get update -y && sudo apt-get install clang++-6
|
||||
fi
|
||||
# we only enable lto for release builds
|
||||
# and therefore don't need to us ld.gold or llvm tools for linking
|
||||
# for debug builds
|
||||
if [[ ${BUILD_TYPE} == 'Release' ]]; then
|
||||
if [[ "${CCOMPILER}" == clang-* ]] && [[ ${BUILD_TYPE} == 'Release' ]]; then
|
||||
${MASON} install binutils 2.27
|
||||
echo "$(${MASON} prefix binutils 2.27)/bin" >> $GITHUB_PATH
|
||||
fi
|
||||
fi
|
||||
|
||||
# Linux dev packages
|
||||
if [ "${TARGET_ARCH}" != "i686" ] && [ "${ENABLE_CONAN}" != "ON" ]; then
|
||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y libbz2-dev libxml2-dev libzip-dev liblua5.2-dev libboost-all-dev
|
||||
if [[ -z "${CLANG_VERSION}" ]]; then
|
||||
if [[ "${CCOMPILER}" != clang-* ]]; then
|
||||
sudo apt-get install -y ${CXXCOMPILER}
|
||||
fi
|
||||
if [[ "${ENABLE_COVERAGE}" == "ON" ]]; then
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
- FIXED: Support `skip_waypoints` in Node bindings [#6060](https://github.com/Project-OSRM/osrm-backend/pull/6060)
|
||||
- Misc:
|
||||
- CHANGED: Optimize RestrictionParser performance. [#6344](https://github.com/Project-OSRM/osrm-backend/pull/6344)
|
||||
- ADDED: Support floats for speed value in traffic updates CSV. [#6327](https://github.com/Project-OSRM/osrm-backend/pull/6327)
|
||||
- CHANGED: Use Lua 5.4 in Docker image. [#6346](https://github.com/Project-OSRM/osrm-backend/pull/6346)
|
||||
- CHANGED: Remove redundant nullptr check. [#6326](https://github.com/Project-OSRM/osrm-backend/pull/6326)
|
||||
- CHANGED: missing files list is included in exception message. [#5360](https://github.com/Project-OSRM/osrm-backend/pull/5360)
|
||||
@ -21,6 +22,7 @@
|
||||
- FIXED: Bug in bicycle profile that caused exceptions if there is a highway=bicycle in the data. [#6296](https://github.com/Project-OSRM/osrm-backend/pull/6296)
|
||||
- FIXED: Internal refactoring of identifier types used in data facade [#6044](https://github.com/Project-OSRM/osrm-backend/pull/6044)
|
||||
- Build:
|
||||
- CHANGED: Use apt-get to install Clang on CI. [#6345](https://github.com/Project-OSRM/osrm-backend/pull/6345)
|
||||
- CHANGED: Fix TBB in case of Conan + NodeJS build. [#6333](https://github.com/Project-OSRM/osrm-backend/pull/6333)
|
||||
- CHANGED: Migrate to modern TBB version. [#6300](https://github.com/Project-OSRM/osrm-backend/pull/6300)
|
||||
- CHANGED: Enable performance-move-const-arg clang-tidy check. [#6319](https://github.com/Project-OSRM/osrm-backend/pull/6319)
|
||||
@ -54,6 +56,7 @@
|
||||
- FIXED: Improvements to maneuver override processing [#6125](https://github.com/Project-OSRM/osrm-backend/pull/6125)
|
||||
- ADDED: Support snapping to multiple ways at an input location. [#5953](https://github.com/Project-OSRM/osrm-backend/pull/5953)
|
||||
- FIXED: Fix snapping target locations to ways used in turn restrictions. [#6339](https://github.com/Project-OSRM/osrm-backend/pull/6339)
|
||||
- ADDED: Support OSM traffic signal directions. [#6153](https://github.com/Project-OSRM/osrm-backend/pull/6153)
|
||||
|
||||
# 5.26.0
|
||||
- Changes from 5.25.0
|
||||
|
||||
@ -39,7 +39,113 @@ Feature: Car - Handle traffic lights
|
||||
| k | n | 20.7s | turn with traffic light |
|
||||
|
||||
|
||||
Scenario: Tarrif Signal Geometry
|
||||
Scenario: Car - Traffic signal direction
|
||||
Given the node map
|
||||
"""
|
||||
a-1-b-2-c
|
||||
|
||||
d-3-e-4-f
|
||||
|
||||
g-5-h-6-i
|
||||
|
||||
j-7-k-8-l
|
||||
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | primary |
|
||||
| def | primary |
|
||||
| ghi | primary |
|
||||
| jkl | primary |
|
||||
|
||||
And the nodes
|
||||
| node | highway | traffic_signals:direction |
|
||||
| e | traffic_signals | |
|
||||
| h | traffic_signals | forward |
|
||||
| k | traffic_signals | backward |
|
||||
|
||||
When I route I should get
|
||||
| from | to | time | # |
|
||||
| 1 | 2 | 11.1s | no turn with no traffic light |
|
||||
| 2 | 1 | 11.1s | no turn with no traffic light |
|
||||
| 3 | 4 | 13.1s | no turn with traffic light |
|
||||
| 4 | 3 | 13.1s | no turn with traffic light |
|
||||
| 5 | 6 | 13.1s | no turn with traffic light |
|
||||
| 6 | 5 | 11.1s | no turn with no traffic light |
|
||||
| 7 | 8 | 11.1s | no turn with no traffic light |
|
||||
| 8 | 7 | 13.1s | no turn with traffic light |
|
||||
|
||||
|
||||
Scenario: Car - Encounters a traffic light
|
||||
Given the node map
|
||||
"""
|
||||
a f k
|
||||
| | |
|
||||
b-c-d h-g-i l-m-n
|
||||
| | |
|
||||
e j o
|
||||
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| bcd | primary |
|
||||
| ace | primary |
|
||||
| hgi | primary |
|
||||
| fgj | primary |
|
||||
| lmn | primary |
|
||||
| kmo | primary |
|
||||
|
||||
And the nodes
|
||||
| node | highway | traffic_signals:direction |
|
||||
| g | traffic_signals | forward |
|
||||
| m | traffic_signals | backward |
|
||||
|
||||
|
||||
When I route I should get
|
||||
| from | to | time | # |
|
||||
| a | d | 21.9s | no turn with no traffic light |
|
||||
| a | e | 22.2s | no turn with traffic light |
|
||||
| a | b | 18.7s | turn with no traffic light |
|
||||
| e | b | 21.9s | no turn with no traffic light |
|
||||
| e | a | 22.2s | no turn with traffic light |
|
||||
| e | d | 18.7s | turn with no traffic light |
|
||||
| d | e | 21.9s | no turn with no traffic light |
|
||||
| d | b | 11s | no turn with traffic light |
|
||||
| d | a | 18.7s | turn with no traffic light |
|
||||
| b | a | 21.9s | no turn with no traffic light |
|
||||
| b | d | 11s | no turn with traffic light |
|
||||
| b | e | 18.7s | turn with no traffic light |
|
||||
|
||||
| f | i | 23.9s | no turn with no traffic light |
|
||||
| f | j | 24.2s | no turn with traffic light |
|
||||
| f | h | 20.7s | turn with no traffic light |
|
||||
| j | h | 21.9s | no turn with no traffic light |
|
||||
| j | f | 22.2s | no turn with traffic light |
|
||||
| j | i | 18.7s | turn with no traffic light |
|
||||
| i | j | 21.9s | no turn with no traffic light |
|
||||
| i | h | 11s | no turn with traffic light |
|
||||
| i | f | 18.7s | turn with no traffic light |
|
||||
| h | f | 23.9s | no turn with no traffic light |
|
||||
| h | i | 13s | no turn with traffic light |
|
||||
| h | j | 20.7s | turn with no traffic light |
|
||||
|
||||
| k | n | 21.9s | no turn with no traffic light |
|
||||
| k | o | 22.2s | no turn with traffic light |
|
||||
| k | l | 18.7s | turn with no traffic light |
|
||||
| o | l | 23.9s | no turn with no traffic light |
|
||||
| o | k | 24.2s | no turn with traffic light |
|
||||
| o | n | 20.7s | turn with no traffic light |
|
||||
| n | o | 23.9s | no turn with no traffic light |
|
||||
| n | l | 13s | no turn with traffic light |
|
||||
| n | k | 20.7s | turn with no traffic light |
|
||||
| l | k | 21.9s | no turn with no traffic light |
|
||||
| l | n | 11s | no turn with traffic light |
|
||||
| l | o | 18.7s | turn with no traffic light |
|
||||
|
||||
|
||||
Scenario: Traffic Signal Geometry
|
||||
Given the query options
|
||||
| overview | full |
|
||||
| geometries | polyline |
|
||||
@ -61,6 +167,53 @@ Feature: Car - Handle traffic lights
|
||||
| from | to | route | geometry |
|
||||
| a | c | abc,abc | _ibE_ibE?gJ?eJ |
|
||||
|
||||
|
||||
Scenario: Traffic Signal Geometry - forward signal
|
||||
Given the query options
|
||||
| overview | full |
|
||||
| geometries | polyline |
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a - b - c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | primary |
|
||||
|
||||
And the nodes
|
||||
| node | highway | traffic_signals:direction |
|
||||
| b | traffic_signals | forward |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | geometry |
|
||||
| a | c | abc,abc | _ibE_ibE?gJ?eJ |
|
||||
|
||||
|
||||
Scenario: Traffic Signal Geometry - reverse signal
|
||||
Given the query options
|
||||
| overview | full |
|
||||
| geometries | polyline |
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a - b - c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | primary |
|
||||
|
||||
And the nodes
|
||||
| node | highway | traffic_signals:direction |
|
||||
| b | traffic_signals | reverse |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | geometry |
|
||||
| a | c | abc,abc | _ibE_ibE?gJ?eJ |
|
||||
|
||||
|
||||
@traffic
|
||||
Scenario: Traffic update on the edge with a traffic signal
|
||||
Given the node map
|
||||
@ -91,3 +244,67 @@ Feature: Car - Handle traffic lights
|
||||
| from | to | route | speed | weights | time | distances | a:datasources | a:nodes | a:speed | a:duration | a:weight |
|
||||
| a | c | abc,abc | 60 km/h | 24.2,0 | 24.2s | 400m,0m | 1:0 | 1:2:3 | 18:18 | 11.1:11.1 | 11.1:11.1 |
|
||||
| c | a | abc,abc | 60 km/h | 24.2,0 | 24.2s | 400m,0m | 0:1 | 3:2:1 | 18:18 | 11.1:11.1 | 11.1:11.1 |
|
||||
|
||||
|
||||
@traffic
|
||||
Scenario: Traffic update on the edge with a traffic signal - forward
|
||||
Given the node map
|
||||
"""
|
||||
a - b - c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | primary |
|
||||
|
||||
|
||||
And the nodes
|
||||
| node | highway | traffic_signals:direction |
|
||||
| b | traffic_signals | forward |
|
||||
|
||||
And the contract extra arguments "--segment-speed-file {speeds_file}"
|
||||
And the customize extra arguments "--segment-speed-file {speeds_file}"
|
||||
And the speed file
|
||||
"""
|
||||
1,2,65
|
||||
2,1,65
|
||||
"""
|
||||
And the query options
|
||||
| annotations | datasources,nodes,speed,duration,weight |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | speed | weights | time | distances | a:datasources | a:nodes | a:speed | a:duration | a:weight |
|
||||
| a | c | abc,abc | 60 km/h | 24.2,0 | 24.2s | 400m,0m | 1:0 | 1:2:3 | 18:18 | 11.1:11.1 | 11.1:11.1 |
|
||||
| c | a | abc,abc | 65 km/h | 22.2,0 | 22.2s | 400m,0m | 0:1 | 3:2:1 | 18:18 | 11.1:11.1 | 11.1:11.1 |
|
||||
|
||||
|
||||
@traffic
|
||||
Scenario: Traffic update on the edge with a traffic signal - backward
|
||||
Given the node map
|
||||
"""
|
||||
a - b - c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | primary |
|
||||
|
||||
|
||||
And the nodes
|
||||
| node | highway | traffic_signals:direction |
|
||||
| b | traffic_signals | backward |
|
||||
|
||||
And the contract extra arguments "--segment-speed-file {speeds_file}"
|
||||
And the customize extra arguments "--segment-speed-file {speeds_file}"
|
||||
And the speed file
|
||||
"""
|
||||
1,2,65
|
||||
2,1,65
|
||||
"""
|
||||
And the query options
|
||||
| annotations | datasources,nodes,speed,duration,weight |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | speed | weights | time | distances | a:datasources | a:nodes | a:speed | a:duration | a:weight |
|
||||
| a | c | abc,abc | 65 km/h | 22.2,0 | 22.2s | 400m,0m | 1:0 | 1:2:3 | 18:18 | 11.1:11.1 | 11.1:11.1 |
|
||||
| c | a | abc,abc | 60 km/h | 24.2,0 | 24.2s | 400m,0m | 0:1 | 3:2:1 | 18:18 | 11.1:11.1 | 11.1:11.1 |
|
||||
|
||||
@ -329,7 +329,7 @@ Feature: Weight tests
|
||||
| ce |
|
||||
And the speed file
|
||||
"""
|
||||
1,2,36,42
|
||||
1,2,36.999,42
|
||||
2,1,36,42
|
||||
"""
|
||||
And the turn penalty file
|
||||
@ -341,8 +341,8 @@ Feature: Weight tests
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | distance | weights | times |
|
||||
| a,d | , | 60m | 20.5,0 | 24s,0s |
|
||||
| a,e | ,, | 60m | 27.2,10,0 | 38.5s,11s,0s |
|
||||
| a,d | , | 60m | 20.5,0 | 23.9s,0s |
|
||||
| a,e | ,, | 60m | 27.2,10,0 | 38.4s,11s,0s |
|
||||
| d,e | ,, | 40m | 10,10,0 | 11s,11s,0s |
|
||||
|
||||
@traffic @speed
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "storage/io.hpp"
|
||||
#include "traffic_signals.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
@ -68,7 +69,7 @@ class EdgeBasedGraphFactory
|
||||
EdgeBasedNodeDataContainer &node_data_container,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const NameTable &name_table,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
@ -134,7 +135,7 @@ class EdgeBasedGraphFactory
|
||||
const util::NodeBasedDynamicGraph &m_node_based_graph;
|
||||
|
||||
const std::unordered_set<NodeID> &m_barrier_nodes;
|
||||
const std::unordered_set<NodeID> &m_traffic_lights;
|
||||
const TrafficSignals &m_traffic_signals;
|
||||
const CompressedEdgeContainer &m_compressed_edge_container;
|
||||
|
||||
const NameTable &name_table;
|
||||
|
||||
@ -8,8 +8,11 @@
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
|
||||
#include "storage/tar_fwd.hpp"
|
||||
#include "traffic_lights.hpp"
|
||||
#include "traffic_signals.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@ -25,15 +28,19 @@ namespace extractor
|
||||
class ExtractionContainers
|
||||
{
|
||||
using ReferencedWays = std::unordered_map<OSMWayID, NodesOfWay>;
|
||||
using ReferencedTrafficSignals =
|
||||
std::pair<std::unordered_set<OSMNodeID>, std::unordered_multimap<OSMNodeID, OSMNodeID>>;
|
||||
// The relationship between way and nodes is lost during node preparation.
|
||||
// We identify the ways and nodes relevant to restrictions/overrides prior to
|
||||
// We identify the ways and nodes relevant to restrictions/overrides/signals prior to
|
||||
// node processing so that they can be referenced in the preparation phase.
|
||||
ReferencedWays IdentifyRestrictionWays();
|
||||
ReferencedWays IdentifyManeuverOverrideWays();
|
||||
ReferencedTrafficSignals IdentifyTrafficSignals();
|
||||
|
||||
void PrepareNodes();
|
||||
void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways);
|
||||
void PrepareRestrictions(const ReferencedWays &restriction_ways);
|
||||
void PrepareTrafficSignals(const ReferencedTrafficSignals &referenced_traffic_signals);
|
||||
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
||||
|
||||
void WriteNodes(storage::tar::FileWriter &file_out) const;
|
||||
@ -50,9 +57,9 @@ class ExtractionContainers
|
||||
using NameOffsets = std::vector<size_t>;
|
||||
using WayIDVector = std::vector<OSMWayID>;
|
||||
using WayNodeIDOffsets = std::vector<size_t>;
|
||||
using InputTrafficSignal = std::pair<OSMNodeID, TrafficLightClass::Direction>;
|
||||
|
||||
std::vector<OSMNodeID> barrier_nodes;
|
||||
std::vector<OSMNodeID> traffic_signals;
|
||||
NodeIDVector used_node_id_list;
|
||||
NodeVector all_nodes_list;
|
||||
EdgeVector all_edges_list;
|
||||
@ -65,6 +72,9 @@ class ExtractionContainers
|
||||
|
||||
unsigned max_internal_node_id;
|
||||
|
||||
std::vector<InputTrafficSignal> external_traffic_signals;
|
||||
TrafficSignals internal_traffic_signals;
|
||||
|
||||
// List of restrictions (conditional and unconditional) before we transform them into the
|
||||
// output types. Input containers reference OSMNodeIDs. We can only transform them to the
|
||||
// correct internal IDs after we've read everything. Without a multi-parse approach,
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#ifndef EXTRACTION_NODE_HPP
|
||||
#define EXTRACTION_NODE_HPP
|
||||
|
||||
#include "traffic_lights.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
@ -8,9 +10,13 @@ namespace extractor
|
||||
|
||||
struct ExtractionNode
|
||||
{
|
||||
ExtractionNode() : traffic_lights(false), barrier(false) {}
|
||||
void clear() { traffic_lights = barrier = false; }
|
||||
bool traffic_lights;
|
||||
ExtractionNode() : traffic_lights(TrafficLightClass::NONE), barrier(false) {}
|
||||
void clear()
|
||||
{
|
||||
traffic_lights = TrafficLightClass::NONE;
|
||||
barrier = false;
|
||||
}
|
||||
TrafficLightClass::Direction traffic_lights;
|
||||
bool barrier;
|
||||
};
|
||||
} // namespace extractor
|
||||
|
||||
@ -43,6 +43,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include "restriction_graph.hpp"
|
||||
#include "traffic_signals.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
namespace osrm
|
||||
@ -64,7 +65,8 @@ class Extractor
|
||||
|
||||
std::tuple<LaneDescriptionMap,
|
||||
std::vector<TurnRestriction>,
|
||||
std::vector<UnresolvedManeuverOverride>>
|
||||
std::vector<UnresolvedManeuverOverride>,
|
||||
TrafficSignals>
|
||||
ParseOSMData(ScriptingEnvironment &scripting_environment, const unsigned number_of_threads);
|
||||
|
||||
EdgeID BuildEdgeExpandedGraph(
|
||||
@ -73,7 +75,7 @@ class Extractor
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const RestrictionGraph &restriction_graph,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
const NameTable &name_table,
|
||||
|
||||
@ -444,10 +444,9 @@ inline void readConditionalRestrictions(const boost::filesystem::path &path,
|
||||
}
|
||||
|
||||
// reads .osrm file which is a temporary file of osrm-extract
|
||||
template <typename BarrierOutIter, typename TrafficSignalsOutIter, typename PackedOSMIDsT>
|
||||
template <typename BarrierOutIter, typename PackedOSMIDsT>
|
||||
void readRawNBGraph(const boost::filesystem::path &path,
|
||||
BarrierOutIter barriers,
|
||||
TrafficSignalsOutIter traffic_signals,
|
||||
std::vector<util::Coordinate> &coordinates,
|
||||
PackedOSMIDsT &osm_node_ids,
|
||||
std::vector<extractor::NodeBasedEdge> &edge_list,
|
||||
@ -471,8 +470,6 @@ void readRawNBGraph(const boost::filesystem::path &path,
|
||||
|
||||
reader.ReadStreaming<NodeID>("/extractor/barriers", barriers);
|
||||
|
||||
reader.ReadStreaming<NodeID>("/extractor/traffic_lights", traffic_signals);
|
||||
|
||||
storage::serialization::read(reader, "/extractor/edges", edge_list);
|
||||
storage::serialization::read(reader, "/extractor/annotations", annotations);
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "traffic_signals.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
#include <memory>
|
||||
@ -25,7 +26,7 @@ class GraphCompressor
|
||||
|
||||
public:
|
||||
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
const TrafficSignals &traffic_signals,
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "extractor/packed_osm_ids.hpp"
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
|
||||
#include "traffic_signals.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
@ -40,11 +41,11 @@ class NodeBasedGraphFactory
|
||||
NodeBasedGraphFactory(const boost::filesystem::path &input_file,
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides);
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
const TrafficSignals &traffic_signals);
|
||||
|
||||
auto const &GetGraph() const { return compressed_output_graph; }
|
||||
auto const &GetBarriers() const { return barriers; }
|
||||
auto const &GetTrafficSignals() const { return traffic_signals; }
|
||||
auto const &GetCompressedEdges() const { return compressed_edge_container; }
|
||||
auto const &GetCoordinates() const { return coordinates; }
|
||||
auto const &GetAnnotationData() const { return annotation_data; }
|
||||
@ -68,7 +69,8 @@ class NodeBasedGraphFactory
|
||||
// edges into a single representative form
|
||||
void Compress(ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides);
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
const TrafficSignals &traffic_signals);
|
||||
|
||||
// Most ways are bidirectional, making the geometry in forward and backward direction the same,
|
||||
// except for reversal. We make use of this fact by keeping only one representation of the
|
||||
@ -89,7 +91,6 @@ class NodeBasedGraphFactory
|
||||
|
||||
// General Information about the graph, not used outside of extractor
|
||||
std::unordered_set<NodeID> barriers;
|
||||
std::unordered_set<NodeID> traffic_signals;
|
||||
|
||||
std::vector<util::Coordinate> coordinates;
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
#include <boost/optional/optional.hpp>
|
||||
|
||||
#include <osmium/tags/tags_filter.hpp>
|
||||
#include <osmium/tags/filter.hpp>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -54,7 +54,7 @@ class RestrictionParser
|
||||
bool use_turn_restrictions;
|
||||
bool parse_conditionals;
|
||||
std::set<std::string> restrictions;
|
||||
osmium::TagsFilter filter;
|
||||
osmium::tags::KeyFilter filter;
|
||||
};
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
25
include/extractor/traffic_lights.hpp
Normal file
25
include/extractor/traffic_lights.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_
|
||||
#define OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
namespace TrafficLightClass
|
||||
{
|
||||
// The traffic light annotation is extracted from node tags.
|
||||
// The directions in which the traffic light applies are relative to the way containing the node.
|
||||
enum Direction
|
||||
{
|
||||
NONE = 0,
|
||||
DIRECTION_ALL = 1,
|
||||
DIRECTION_FORWARD = 2,
|
||||
DIRECTION_REVERSE = 3
|
||||
};
|
||||
} // namespace TrafficLightClass
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_
|
||||
28
include/extractor/traffic_signals.hpp
Normal file
28
include/extractor/traffic_signals.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP
|
||||
#define OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
#include <unordered_set>
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
struct TrafficSignals
|
||||
{
|
||||
std::unordered_set<NodeID> bidirectional_nodes;
|
||||
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
|
||||
unidirectional_segments;
|
||||
|
||||
inline bool HasSignal(NodeID from, NodeID to) const
|
||||
{
|
||||
return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0;
|
||||
}
|
||||
};
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP
|
||||
@ -49,8 +49,8 @@ struct Segment final
|
||||
|
||||
struct SpeedSource final
|
||||
{
|
||||
SpeedSource() : speed(0), rate() {}
|
||||
unsigned speed;
|
||||
SpeedSource() : speed(0.), rate() {}
|
||||
double speed;
|
||||
boost::optional<double> rate;
|
||||
std::uint8_t source;
|
||||
};
|
||||
|
||||
@ -5,6 +5,7 @@ api_version = 4
|
||||
Set = require('lib/set')
|
||||
Sequence = require('lib/sequence')
|
||||
Handlers = require("lib/way_handlers")
|
||||
TrafficSignal = require("lib/traffic_signal")
|
||||
find_access_tag = require("lib/access").find_access_tag
|
||||
limit = require("lib/maxspeed").limit
|
||||
Measure = require("lib/measure")
|
||||
@ -235,10 +236,7 @@ function process_node(profile, node, result)
|
||||
end
|
||||
|
||||
-- check if node is a traffic light
|
||||
local tag = node:get_value_by_key("highway")
|
||||
if tag and "traffic_signals" == tag then
|
||||
result.traffic_lights = true
|
||||
end
|
||||
result.traffic_lights = TrafficSignal.get_value(node)
|
||||
end
|
||||
|
||||
function handle_bicycle_tags(profile,way,result,data)
|
||||
|
||||
@ -6,6 +6,7 @@ Set = require('lib/set')
|
||||
Sequence = require('lib/sequence')
|
||||
Handlers = require("lib/way_handlers")
|
||||
Relations = require("lib/relations")
|
||||
TrafficSignal = require("lib/traffic_signal")
|
||||
find_access_tag = require("lib/access").find_access_tag
|
||||
limit = require("lib/maxspeed").limit
|
||||
Utils = require("lib/utils")
|
||||
@ -360,10 +361,7 @@ function process_node(profile, node, result, relations)
|
||||
end
|
||||
|
||||
-- check if node is a traffic light
|
||||
local tag = node:get_value_by_key("highway")
|
||||
if "traffic_signals" == tag then
|
||||
result.traffic_lights = true
|
||||
end
|
||||
result.traffic_lights = TrafficSignal.get_value(node)
|
||||
end
|
||||
|
||||
function process_way(profile, way, result, relations)
|
||||
|
||||
@ -157,6 +157,7 @@ function process_node(profile, node, result)
|
||||
-- check if node is a traffic light
|
||||
local tag = node:get_value_by_key("highway")
|
||||
if "traffic_signals" == tag then
|
||||
-- Direction should only apply to vehicles
|
||||
result.traffic_lights = true
|
||||
end
|
||||
end
|
||||
|
||||
26
profiles/lib/traffic_signal.lua
Normal file
26
profiles/lib/traffic_signal.lua
Normal file
@ -0,0 +1,26 @@
|
||||
-- Assigns traffic light value to node as defined by
|
||||
-- include/extractor/traffic_lights.hpp
|
||||
|
||||
local TrafficSignal = {}
|
||||
|
||||
function TrafficSignal.get_value(node)
|
||||
local tag = node:get_value_by_key("highway")
|
||||
if "traffic_signals" == tag then
|
||||
local direction = node:get_value_by_key("traffic_signals:direction")
|
||||
if direction then
|
||||
if "forward" == direction then
|
||||
return traffic_lights.direction_forward
|
||||
end
|
||||
if "backward" == direction then
|
||||
return traffic_lights.direction_reverse
|
||||
end
|
||||
end
|
||||
-- return traffic_lights.direction_all
|
||||
return true
|
||||
end
|
||||
-- return traffic_lights.none
|
||||
return false
|
||||
end
|
||||
|
||||
return TrafficSignal
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
-- Primary road: 36km/h = 36000m/3600s = 100m/10s
|
||||
-- Secondary road: 18km/h = 18000m/3600s = 100m/20s
|
||||
-- Tertiary road: 12km/h = 12000m/3600s = 100m/30s
|
||||
TrafficSignal = require("lib/traffic_signal")
|
||||
|
||||
api_version = 4
|
||||
|
||||
@ -38,12 +39,9 @@ function setup()
|
||||
end
|
||||
|
||||
function process_node (profile, node, result)
|
||||
local traffic_signal = node:get_value_by_key("highway")
|
||||
|
||||
if traffic_signal and traffic_signal == "traffic_signals" then
|
||||
result.traffic_lights = true
|
||||
-- check if node is a traffic light
|
||||
result.traffic_lights = TrafficSignal.get_value(node)
|
||||
-- TODO: a way to set the penalty value
|
||||
end
|
||||
end
|
||||
|
||||
function process_way (profile, way, result)
|
||||
|
||||
@ -59,7 +59,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
||||
EdgeBasedNodeDataContainer &node_data_container,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const NameTable &name_table,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
@ -67,7 +67,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
||||
: m_edge_based_node_container(node_data_container), m_connectivity_checksum(0),
|
||||
m_number_of_edge_based_nodes(0), m_coordinates(coordinates),
|
||||
m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes),
|
||||
m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container),
|
||||
m_traffic_signals(traffic_signals), m_compressed_edge_container(compressed_edge_container),
|
||||
name_table(name_table), segregated_edges(segregated_edges),
|
||||
lane_description_map(lane_description_map)
|
||||
{
|
||||
@ -623,8 +623,26 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
BOOST_ASSERT(!edge_data1.reversed);
|
||||
BOOST_ASSERT(!edge_data2.reversed);
|
||||
|
||||
// We write out the mapping between the edge-expanded edges and the original nodes.
|
||||
// Since each edge represents a possible maneuver, external programs can use this to
|
||||
// quickly perform updates to edge weights in order to penalize certain turns.
|
||||
|
||||
// If this edge is 'trivial' -- where the compressed edge corresponds exactly to an
|
||||
// original OSM segment -- we can pull the turn's preceding node ID directly with
|
||||
// `node_along_road_entering`;
|
||||
// otherwise, we need to look up the node immediately preceding the turn from the
|
||||
// compressed edge container.
|
||||
const bool isTrivial = m_compressed_edge_container.IsTrivial(node_based_edge_from);
|
||||
|
||||
const auto &from_node =
|
||||
isTrivial ? node_along_road_entering
|
||||
: m_compressed_edge_container.GetLastEdgeSourceID(node_based_edge_from);
|
||||
|
||||
// compute weight and duration penalties
|
||||
const auto is_traffic_light = m_traffic_lights.count(intersection_node);
|
||||
// In theory we shouldn't get a directed traffic light on a turn, as it indicates that
|
||||
// the traffic signal direction was potentially ambiguously annotated on the junction
|
||||
// node But we'll check anyway.
|
||||
const auto is_traffic_light = m_traffic_signals.HasSignal(from_node, intersection_node);
|
||||
const auto is_uturn =
|
||||
guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn;
|
||||
|
||||
@ -690,20 +708,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
true,
|
||||
false};
|
||||
|
||||
// We write out the mapping between the edge-expanded edges and the original nodes.
|
||||
// Since each edge represents a possible maneuver, external programs can use this to
|
||||
// quickly perform updates to edge weights in order to penalize certain turns.
|
||||
|
||||
// If this edge is 'trivial' -- where the compressed edge corresponds exactly to an
|
||||
// original OSM segment -- we can pull the turn's preceding node ID directly with
|
||||
// `node_along_road_entering`;
|
||||
// otherwise, we need to look up the node immediately preceding the turn from the
|
||||
// compressed edge container.
|
||||
const bool isTrivial = m_compressed_edge_container.IsTrivial(node_based_edge_from);
|
||||
|
||||
const auto &from_node =
|
||||
isTrivial ? node_along_road_entering
|
||||
: m_compressed_edge_container.GetLastEdgeSourceID(node_based_edge_from);
|
||||
const auto &to_node =
|
||||
m_compressed_edge_container.GetFirstEdgeTargetID(node_based_edge_to);
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "util/exception.hpp"
|
||||
#include "util/exception_utils.hpp"
|
||||
#include "util/for_each_indexed.hpp"
|
||||
#include "util/for_each_pair.hpp"
|
||||
#include "util/log.hpp"
|
||||
#include "util/timing_util.hpp"
|
||||
|
||||
@ -413,6 +414,7 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme
|
||||
|
||||
const auto restriction_ways = IdentifyRestrictionWays();
|
||||
const auto maneuver_override_ways = IdentifyManeuverOverrideWays();
|
||||
const auto traffic_signals = IdentifyTrafficSignals();
|
||||
|
||||
PrepareNodes();
|
||||
WriteNodes(writer);
|
||||
@ -422,6 +424,7 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme
|
||||
WriteEdges(writer);
|
||||
WriteMetadata(writer);
|
||||
|
||||
PrepareTrafficSignals(traffic_signals);
|
||||
PrepareManeuverOverrides(maneuver_override_ways);
|
||||
PrepareRestrictions(restriction_ways);
|
||||
WriteCharData(name_file_name);
|
||||
@ -911,25 +914,6 @@ void ExtractionContainers::WriteNodes(storage::tar::FileWriter &writer) const
|
||||
log << "ok, after " << TIMER_SEC(write_nodes) << "s";
|
||||
}
|
||||
|
||||
{
|
||||
util::UnbufferedLog log;
|
||||
log << "Writing traffic light nodes ... ";
|
||||
TIMER_START(write_nodes);
|
||||
std::vector<NodeID> internal_traffic_signals;
|
||||
for (const auto osm_id : traffic_signals)
|
||||
{
|
||||
const auto node_id = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), osm_id);
|
||||
if (node_id != SPECIAL_NODEID)
|
||||
{
|
||||
internal_traffic_signals.push_back(node_id);
|
||||
}
|
||||
}
|
||||
storage::serialization::write(
|
||||
writer, "/extractor/traffic_lights", internal_traffic_signals);
|
||||
log << "ok, after " << TIMER_SEC(write_nodes) << "s";
|
||||
}
|
||||
|
||||
util::Log() << "Processed " << max_internal_node_id << " nodes";
|
||||
}
|
||||
|
||||
@ -983,6 +967,50 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
|
||||
return maneuver_override_ways;
|
||||
}
|
||||
|
||||
void ExtractionContainers::PrepareTrafficSignals(
|
||||
const ExtractionContainers::ReferencedTrafficSignals &referenced_traffic_signals)
|
||||
{
|
||||
const auto &bidirectional_signal_nodes = referenced_traffic_signals.first;
|
||||
const auto &unidirectional_signal_segments = referenced_traffic_signals.second;
|
||||
|
||||
util::UnbufferedLog log;
|
||||
log << "Preparing traffic light signals for " << bidirectional_signal_nodes.size()
|
||||
<< " bidirectional, " << unidirectional_signal_segments.size()
|
||||
<< " unidirectional nodes ...";
|
||||
TIMER_START(prepare_traffic_signals);
|
||||
|
||||
std::unordered_set<NodeID> bidirectional;
|
||||
std::unordered_set<std::pair<NodeID, NodeID>, boost::hash<std::pair<NodeID, NodeID>>>
|
||||
unidirectional;
|
||||
|
||||
for (const auto &osm_node : bidirectional_signal_nodes)
|
||||
{
|
||||
const auto node_id = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
||||
if (node_id != SPECIAL_NODEID)
|
||||
{
|
||||
bidirectional.insert(node_id);
|
||||
}
|
||||
}
|
||||
for (const auto &to_from : unidirectional_signal_segments)
|
||||
{
|
||||
const auto to_node_id = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), to_from.first);
|
||||
const auto from_node_id = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), to_from.second);
|
||||
if (from_node_id != SPECIAL_NODEID && to_node_id != SPECIAL_NODEID)
|
||||
{
|
||||
unidirectional.insert({from_node_id, to_node_id});
|
||||
}
|
||||
}
|
||||
|
||||
internal_traffic_signals.bidirectional_nodes = std::move(bidirectional);
|
||||
internal_traffic_signals.unidirectional_segments = std::move(unidirectional);
|
||||
|
||||
TIMER_STOP(prepare_traffic_signals);
|
||||
log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s";
|
||||
}
|
||||
|
||||
void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways)
|
||||
{
|
||||
auto const osm_node_to_internal_nbn = [&](auto const osm_node) {
|
||||
@ -1163,6 +1191,93 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
|
||||
return restriction_ways;
|
||||
}
|
||||
|
||||
ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTrafficSignals()
|
||||
{
|
||||
util::UnbufferedLog log;
|
||||
log << "Collecting traffic signal information on " << external_traffic_signals.size()
|
||||
<< " signals...";
|
||||
TIMER_START(identify_traffic_signals);
|
||||
|
||||
// Temporary store for nodes containing a unidirectional signal.
|
||||
std::unordered_map<OSMNodeID, TrafficLightClass::Direction> unidirectional_signals;
|
||||
|
||||
// For each node that has a unidirectional traffic signal, we store the node(s)
|
||||
// that lead up to the signal.
|
||||
std::unordered_multimap<OSMNodeID, OSMNodeID> signal_segments;
|
||||
|
||||
std::unordered_set<OSMNodeID> bidirectional_signals;
|
||||
|
||||
const auto mark_signals = [&](auto const &traffic_signal) {
|
||||
if (traffic_signal.second == TrafficLightClass::DIRECTION_FORWARD ||
|
||||
traffic_signal.second == TrafficLightClass::DIRECTION_REVERSE)
|
||||
{
|
||||
unidirectional_signals.insert({traffic_signal.first, traffic_signal.second});
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(traffic_signal.second == TrafficLightClass::DIRECTION_ALL);
|
||||
bidirectional_signals.insert(traffic_signal.first);
|
||||
}
|
||||
};
|
||||
std::for_each(external_traffic_signals.begin(), external_traffic_signals.end(), mark_signals);
|
||||
|
||||
// Extract all the segments that lead up to unidirectional traffic signals.
|
||||
const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) {
|
||||
const auto node_start_offset =
|
||||
used_node_id_list.begin() + way_node_id_offsets[way_list_idx];
|
||||
const auto node_end_offset =
|
||||
used_node_id_list.begin() + way_node_id_offsets[way_list_idx + 1];
|
||||
|
||||
for (auto node_it = node_start_offset; node_it < node_end_offset; node_it++)
|
||||
{
|
||||
const auto sig = unidirectional_signals.find(*node_it);
|
||||
if (sig != unidirectional_signals.end())
|
||||
{
|
||||
if (sig->second == TrafficLightClass::DIRECTION_FORWARD)
|
||||
{
|
||||
if (node_it != node_start_offset)
|
||||
{
|
||||
// Previous node leads to signal
|
||||
signal_segments.insert({*node_it, *(node_it - 1)});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(sig->second == TrafficLightClass::DIRECTION_REVERSE);
|
||||
if (node_it + 1 != node_end_offset)
|
||||
{
|
||||
// Next node leads to signal
|
||||
signal_segments.insert({*node_it, *(node_it + 1)});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments);
|
||||
|
||||
util::for_each_pair(
|
||||
signal_segments, [](const auto pair_a, const auto pair_b) {
|
||||
if (pair_a.first == pair_b.first)
|
||||
{
|
||||
// If a node is appearing multiple times in this map, then it's ambiguous.
|
||||
// The node is an intersection and the traffic direction is being use for multiple
|
||||
// ways. We can't be certain of the original intent. See:
|
||||
// https://wiki.openstreetmap.org/wiki/Key:traffic_signals:direction
|
||||
|
||||
// OSRM will include the signal for all intersecting ways in the specified
|
||||
// direction, but let's flag this as a concern.
|
||||
util::Log(logWARNING)
|
||||
<< "OSM node " << pair_a.first
|
||||
<< " has a unidirectional traffic signal ambiguously applied to multiple ways";
|
||||
}
|
||||
});
|
||||
|
||||
TIMER_STOP(identify_traffic_signals);
|
||||
log << "ok, after " << TIMER_SEC(identify_traffic_signals) << "s";
|
||||
|
||||
return {std::move(bidirectional_signals), std::move(signal_segments)};
|
||||
}
|
||||
|
||||
void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways)
|
||||
{
|
||||
|
||||
|
||||
@ -75,7 +75,7 @@ void SetClassNames(const std::vector<std::string> &class_names,
|
||||
if (!class_names.empty())
|
||||
{
|
||||
// add class names that were never used explicitly on a way
|
||||
// this makes sure we can correctly validate unkown class names later
|
||||
// this makes sure we can correctly validate unknown class names later
|
||||
for (const auto &name : class_names)
|
||||
{
|
||||
if (!isValidClassName(name))
|
||||
@ -207,7 +207,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
||||
LaneDescriptionMap turn_lane_map;
|
||||
std::vector<TurnRestriction> turn_restrictions;
|
||||
std::vector<UnresolvedManeuverOverride> unresolved_maneuver_overrides;
|
||||
std::tie(turn_lane_map, turn_restrictions, unresolved_maneuver_overrides) =
|
||||
TrafficSignals traffic_signals;
|
||||
std::tie(turn_lane_map, turn_restrictions, unresolved_maneuver_overrides, traffic_signals) =
|
||||
ParseOSMData(scripting_environment, number_of_threads);
|
||||
|
||||
// Transform the node-based graph that OSM is based on into an edge-based graph
|
||||
@ -229,7 +230,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
||||
NodeBasedGraphFactory node_based_graph_factory(config.GetPath(".osrm"),
|
||||
scripting_environment,
|
||||
turn_restrictions,
|
||||
unresolved_maneuver_overrides);
|
||||
unresolved_maneuver_overrides,
|
||||
traffic_signals);
|
||||
|
||||
NameTable name_table;
|
||||
files::readNames(config.GetPath(".osrm.names"), name_table);
|
||||
@ -264,7 +266,6 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
||||
node_based_graph_factory.GetCompressedEdges().PrintStatistics();
|
||||
|
||||
const auto &barrier_nodes = node_based_graph_factory.GetBarriers();
|
||||
const auto &traffic_signals = node_based_graph_factory.GetTrafficSignals();
|
||||
// stealing the annotation data from the node-based graph
|
||||
edge_based_nodes_container =
|
||||
EdgeBasedNodeDataContainer({}, std::move(node_based_graph_factory.GetAnnotationData()));
|
||||
@ -360,9 +361,11 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::
|
||||
tuple<LaneDescriptionMap, std::vector<TurnRestriction>, std::vector<UnresolvedManeuverOverride>>
|
||||
Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
std::tuple<LaneDescriptionMap,
|
||||
std::vector<TurnRestriction>,
|
||||
std::vector<UnresolvedManeuverOverride>,
|
||||
TrafficSignals>
|
||||
Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
const unsigned number_of_threads)
|
||||
{
|
||||
TIMER_START(extracting);
|
||||
@ -628,7 +631,8 @@ std::
|
||||
|
||||
return std::make_tuple(std::move(turn_lane_map),
|
||||
std::move(extraction_containers.turn_restrictions),
|
||||
std::move(extraction_containers.internal_maneuver_overrides));
|
||||
std::move(extraction_containers.internal_maneuver_overrides),
|
||||
std::move(extraction_containers.internal_traffic_signals));
|
||||
}
|
||||
|
||||
void Extractor::FindComponents(unsigned number_of_edge_based_nodes,
|
||||
@ -699,7 +703,7 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_signals,
|
||||
const TrafficSignals &traffic_signals,
|
||||
const RestrictionGraph &restriction_graph,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
const NameTable &name_table,
|
||||
|
||||
@ -78,9 +78,9 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node,
|
||||
{
|
||||
external_memory.barrier_nodes.push_back(id);
|
||||
}
|
||||
if (result_node.traffic_lights)
|
||||
if (result_node.traffic_lights != TrafficLightClass::NONE)
|
||||
{
|
||||
external_memory.traffic_signals.push_back(id);
|
||||
external_memory.external_traffic_signals.push_back({id, result_node.traffic_lights});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,8 +19,10 @@ namespace osrm
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
static constexpr int SECOND_TO_DECISECOND = 10;
|
||||
|
||||
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_signals,
|
||||
const TrafficSignals &traffic_signals,
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
@ -207,16 +209,20 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
rev_edge_data2.annotation_data, rev_edge_data1.annotation_data);
|
||||
|
||||
// Add node penalty when compress edge crosses a traffic signal
|
||||
const bool has_node_penalty = traffic_signals.find(node_v) != traffic_signals.end();
|
||||
EdgeDuration node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
||||
EdgeWeight node_weight_penalty = INVALID_EDGE_WEIGHT;
|
||||
if (has_node_penalty)
|
||||
const bool has_forward_signal = traffic_signals.HasSignal(node_u, node_v);
|
||||
const bool has_reverse_signal = traffic_signals.HasSignal(node_w, node_v);
|
||||
|
||||
EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
||||
EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
||||
EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION;
|
||||
EdgeWeight reverse_node_weight_penalty = INVALID_EDGE_WEIGHT;
|
||||
if (has_forward_signal || has_reverse_signal)
|
||||
{
|
||||
// we cannot handle this as node penalty, if it depends on turn direction
|
||||
if (fwd_edge_data1.flags.restricted != fwd_edge_data2.flags.restricted)
|
||||
continue;
|
||||
|
||||
// generate an artifical turn for the turn penalty generation
|
||||
// generate an artificial turn for the turn penalty generation
|
||||
std::vector<ExtractionTurnLeg> roads_on_the_right;
|
||||
std::vector<ExtractionTurnLeg> roads_on_the_left;
|
||||
ExtractionTurn extraction_turn(0,
|
||||
@ -245,8 +251,24 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
roads_on_the_right,
|
||||
roads_on_the_left);
|
||||
scripting_environment.ProcessTurn(extraction_turn);
|
||||
node_duration_penalty = extraction_turn.duration * 10;
|
||||
node_weight_penalty = extraction_turn.weight * weight_multiplier;
|
||||
|
||||
auto update_direction_penalty =
|
||||
[&extraction_turn, weight_multiplier](bool signal,
|
||||
EdgeDuration &duration_penalty,
|
||||
EdgeWeight &weight_penalty) {
|
||||
if (signal)
|
||||
{
|
||||
duration_penalty = extraction_turn.duration * SECOND_TO_DECISECOND;
|
||||
weight_penalty = extraction_turn.weight * weight_multiplier;
|
||||
}
|
||||
};
|
||||
|
||||
update_direction_penalty(has_forward_signal,
|
||||
forward_node_duration_penalty,
|
||||
forward_node_weight_penalty);
|
||||
update_direction_penalty(has_reverse_signal,
|
||||
reverse_node_duration_penalty,
|
||||
reverse_node_weight_penalty);
|
||||
}
|
||||
|
||||
// Get weights before graph is modified
|
||||
@ -278,27 +300,37 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
BOOST_ASSERT(0 != reverse_weight1);
|
||||
BOOST_ASSERT(0 != reverse_weight2);
|
||||
|
||||
// add weight of e2's to e1
|
||||
graph.GetEdgeData(forward_e1).weight += forward_weight2;
|
||||
graph.GetEdgeData(reverse_e1).weight += reverse_weight2;
|
||||
|
||||
// add duration of e2's to e1
|
||||
graph.GetEdgeData(forward_e1).duration += forward_duration2;
|
||||
graph.GetEdgeData(reverse_e1).duration += reverse_duration2;
|
||||
|
||||
// add distance of e2's to e1
|
||||
graph.GetEdgeData(forward_e1).distance += forward_distance2;
|
||||
graph.GetEdgeData(reverse_e1).distance += reverse_distance2;
|
||||
|
||||
if (node_weight_penalty != INVALID_EDGE_WEIGHT &&
|
||||
node_duration_penalty != MAXIMAL_EDGE_DURATION)
|
||||
auto apply_e2_to_e1 = [&graph](EdgeID edge,
|
||||
EdgeWeight weight,
|
||||
EdgeDuration duration,
|
||||
EdgeDistance distance,
|
||||
EdgeDuration &duration_penalty,
|
||||
EdgeWeight &weight_penalty) {
|
||||
auto &edge_data = graph.GetEdgeData(edge);
|
||||
edge_data.weight += weight;
|
||||
edge_data.duration += duration;
|
||||
edge_data.distance += distance;
|
||||
if (weight_penalty != INVALID_EDGE_WEIGHT &&
|
||||
duration_penalty != MAXIMAL_EDGE_DURATION)
|
||||
{
|
||||
graph.GetEdgeData(forward_e1).weight += node_weight_penalty;
|
||||
graph.GetEdgeData(reverse_e1).weight += node_weight_penalty;
|
||||
graph.GetEdgeData(forward_e1).duration += node_duration_penalty;
|
||||
graph.GetEdgeData(reverse_e1).duration += node_duration_penalty;
|
||||
edge_data.weight += weight_penalty;
|
||||
edge_data.duration += duration_penalty;
|
||||
// Note: no penalties for distances
|
||||
}
|
||||
};
|
||||
|
||||
apply_e2_to_e1(forward_e1,
|
||||
forward_weight2,
|
||||
forward_duration2,
|
||||
forward_distance2,
|
||||
forward_node_weight_penalty,
|
||||
forward_node_duration_penalty);
|
||||
apply_e2_to_e1(reverse_e1,
|
||||
reverse_weight2,
|
||||
reverse_duration2,
|
||||
reverse_distance2,
|
||||
reverse_node_weight_penalty,
|
||||
reverse_node_duration_penalty);
|
||||
|
||||
// extend e1's to targets of e2's
|
||||
graph.SetTarget(forward_e1, node_w);
|
||||
@ -311,6 +343,25 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
// update any involved turn relations
|
||||
turn_path_compressor.Compress(node_u, node_v, node_w);
|
||||
|
||||
// Forward and reversed compressed edge lengths need to match.
|
||||
// Set a dummy empty penalty weight if opposite value exists.
|
||||
auto set_dummy_penalty = [](EdgeWeight &weight_penalty,
|
||||
EdgeDuration &duration_penalty,
|
||||
EdgeWeight &other_weight_penalty) {
|
||||
if (weight_penalty == INVALID_EDGE_WEIGHT &&
|
||||
other_weight_penalty != INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
weight_penalty = 0;
|
||||
duration_penalty = 0;
|
||||
}
|
||||
};
|
||||
set_dummy_penalty(forward_node_weight_penalty,
|
||||
forward_node_duration_penalty,
|
||||
reverse_node_weight_penalty);
|
||||
set_dummy_penalty(reverse_node_weight_penalty,
|
||||
reverse_node_duration_penalty,
|
||||
forward_node_weight_penalty);
|
||||
|
||||
// store compressed geometry in container
|
||||
geometry_compressor.CompressEdge(forward_e1,
|
||||
forward_e2,
|
||||
@ -320,8 +371,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
forward_weight2,
|
||||
forward_duration1,
|
||||
forward_duration2,
|
||||
node_weight_penalty,
|
||||
node_duration_penalty);
|
||||
forward_node_weight_penalty,
|
||||
forward_node_duration_penalty);
|
||||
geometry_compressor.CompressEdge(reverse_e1,
|
||||
reverse_e2,
|
||||
node_v,
|
||||
@ -330,8 +381,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
reverse_weight2,
|
||||
reverse_duration1,
|
||||
reverse_duration2,
|
||||
node_weight_penalty,
|
||||
node_duration_penalty);
|
||||
reverse_node_weight_penalty,
|
||||
reverse_node_duration_penalty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,10 +19,11 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
|
||||
const boost::filesystem::path &input_file,
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides)
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
const TrafficSignals &traffic_signals)
|
||||
{
|
||||
LoadDataFromFile(input_file);
|
||||
Compress(scripting_environment, turn_restrictions, maneuver_overrides);
|
||||
Compress(scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals);
|
||||
CompressGeometry();
|
||||
CompressAnnotationData();
|
||||
}
|
||||
@ -31,16 +32,10 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
|
||||
void NodeBasedGraphFactory::LoadDataFromFile(const boost::filesystem::path &input_file)
|
||||
{
|
||||
auto barriers_iter = inserter(barriers, end(barriers));
|
||||
auto traffic_signals_iter = inserter(traffic_signals, end(traffic_signals));
|
||||
std::vector<NodeBasedEdge> edge_list;
|
||||
|
||||
files::readRawNBGraph(input_file,
|
||||
barriers_iter,
|
||||
traffic_signals_iter,
|
||||
coordinates,
|
||||
osm_node_ids,
|
||||
edge_list,
|
||||
annotation_data);
|
||||
files::readRawNBGraph(
|
||||
input_file, barriers_iter, coordinates, osm_node_ids, edge_list, annotation_data);
|
||||
|
||||
const auto number_of_node_based_nodes = coordinates.size();
|
||||
if (edge_list.empty())
|
||||
@ -80,7 +75,8 @@ void NodeBasedGraphFactory::LoadDataFromFile(const boost::filesystem::path &inpu
|
||||
|
||||
void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides)
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
const TrafficSignals &traffic_signals)
|
||||
{
|
||||
GraphCompressor graph_compressor;
|
||||
graph_compressor.Compress(barriers,
|
||||
|
||||
@ -44,13 +44,13 @@ RestrictionParser::RestrictionParser(bool use_turn_restrictions_,
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
filter.add_rule(true, "restriction"s);
|
||||
filter.add(true, "restriction"s);
|
||||
if (parse_conditionals)
|
||||
{
|
||||
filter.add_rule(true, "restriction:conditional"s);
|
||||
filter.add(true, "restriction:conditional"s);
|
||||
for (const auto &namespaced : restrictions_)
|
||||
{
|
||||
filter.add_rule(true, "restriction:" + namespaced + ":conditional");
|
||||
filter.add(true, "restriction:" + namespaced + ":conditional");
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ RestrictionParser::RestrictionParser(bool use_turn_restrictions_,
|
||||
// Include restriction:{mode}:conditional if flagged
|
||||
for (const auto &namespaced : restrictions_)
|
||||
{
|
||||
filter.add_rule(true, "restriction:" + namespaced);
|
||||
filter.add(true, "restriction:" + namespaced);
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,8 +81,8 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
|
||||
|
||||
const osmium::TagList &tag_list = relation.tags();
|
||||
|
||||
osmium::TagsFilter::iterator fi_begin(filter, tag_list.begin(), tag_list.end());
|
||||
osmium::TagsFilter::iterator fi_end(filter, tag_list.end(), tag_list.end());
|
||||
osmium::tags::KeyFilter::iterator fi_begin(filter, tag_list.begin(), tag_list.end());
|
||||
osmium::tags::KeyFilter::iterator fi_end(filter, tag_list.end(), tag_list.end());
|
||||
|
||||
// if it's not a restriction, continue;
|
||||
if (fi_begin == fi_end)
|
||||
|
||||
@ -285,9 +285,39 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
return get_location_tag(context, node.location(), key);
|
||||
});
|
||||
|
||||
context.state.new_usertype<ExtractionNode>("ResultNode",
|
||||
context.state.new_enum("traffic_lights",
|
||||
"none",
|
||||
extractor::TrafficLightClass::NONE,
|
||||
"direction_all",
|
||||
extractor::TrafficLightClass::DIRECTION_ALL,
|
||||
"direction_forward",
|
||||
extractor::TrafficLightClass::DIRECTION_FORWARD,
|
||||
"direction_reverse",
|
||||
extractor::TrafficLightClass::DIRECTION_REVERSE);
|
||||
|
||||
context.state.new_usertype<ExtractionNode>(
|
||||
"ResultNode",
|
||||
"traffic_lights",
|
||||
&ExtractionNode::traffic_lights,
|
||||
sol::property([](const ExtractionNode &node) { return node.traffic_lights; },
|
||||
[](ExtractionNode &node, const sol::object &obj) {
|
||||
if (obj.is<bool>())
|
||||
{
|
||||
// The old approach of assigning a boolean traffic light
|
||||
// state to the node is converted to the class enum
|
||||
// TODO: Make a breaking API change and remove this option.
|
||||
bool val = obj.as<bool>();
|
||||
node.traffic_lights = (val) ? TrafficLightClass::DIRECTION_ALL
|
||||
: TrafficLightClass::NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(obj.is<TrafficLightClass::Direction>());
|
||||
{
|
||||
TrafficLightClass::Direction val =
|
||||
obj.as<TrafficLightClass::Direction>();
|
||||
node.traffic_lights = val;
|
||||
}
|
||||
}),
|
||||
"barrier",
|
||||
&ExtractionNode::barrier);
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ std::size_t loadGraph(const std::string &path,
|
||||
auto nop = boost::make_function_output_iterator([](auto) {});
|
||||
|
||||
extractor::files::readRawNBGraph(
|
||||
path, nop, nop, coordinate_list, osm_node_ids, edge_list, annotation_data);
|
||||
path, nop, coordinate_list, osm_node_ids, edge_list, annotation_data);
|
||||
|
||||
// Building a node-based graph
|
||||
for (const auto &input_edge : edge_list)
|
||||
|
||||
@ -34,10 +34,11 @@ namespace csv
|
||||
SegmentLookupTable readSegmentValues(const std::vector<std::string> &paths)
|
||||
{
|
||||
static const auto value_if_blank = std::numeric_limits<double>::quiet_NaN();
|
||||
const qi::real_parser<double, qi::ureal_policies<double>> unsigned_double;
|
||||
CSVFilesParser<Segment, SpeedSource> parser(
|
||||
1,
|
||||
qi::ulong_long >> ',' >> qi::ulong_long,
|
||||
qi::uint_ >> -(',' >> (qi::double_ | qi::attr(value_if_blank))));
|
||||
unsigned_double >> -(',' >> (qi::double_ | qi::attr(value_if_blank))));
|
||||
|
||||
// Check consistency of keys in the result lookup table
|
||||
auto result = parser(paths);
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
@ -66,7 +65,7 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
||||
GraphCompressor compressor;
|
||||
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
std::unordered_set<NodeID> traffic_lights;
|
||||
TrafficSignals traffic_lights;
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||
CompressedEdgeContainer container;
|
||||
@ -112,7 +111,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
||||
GraphCompressor compressor;
|
||||
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
std::unordered_set<NodeID> traffic_lights;
|
||||
TrafficSignals traffic_lights;
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||
@ -175,7 +174,7 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
||||
GraphCompressor compressor;
|
||||
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
std::unordered_set<NodeID> traffic_lights;
|
||||
TrafficSignals traffic_lights;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
@ -218,7 +217,7 @@ BOOST_AUTO_TEST_CASE(street_name_changes)
|
||||
GraphCompressor compressor;
|
||||
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
std::unordered_set<NodeID> traffic_lights;
|
||||
TrafficSignals traffic_lights;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(2);
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
@ -256,7 +255,7 @@ BOOST_AUTO_TEST_CASE(direction_changes)
|
||||
GraphCompressor compressor;
|
||||
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
std::unordered_set<NodeID> traffic_lights;
|
||||
TrafficSignals traffic_lights;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
|
||||
@ -19,7 +19,7 @@ using Graph = util::NodeBasedDynamicGraph;
|
||||
BOOST_AUTO_TEST_CASE(simple_intersection_connectivity)
|
||||
{
|
||||
std::unordered_set<NodeID> barrier_nodes{6};
|
||||
std::unordered_set<NodeID> traffic_lights;
|
||||
TrafficSignals traffic_lights;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations{
|
||||
{EMPTY_NAMEID, 0, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false},
|
||||
{EMPTY_NAMEID, 1, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}};
|
||||
@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(simple_intersection_connectivity)
|
||||
BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity)
|
||||
{
|
||||
std::unordered_set<NodeID> barrier_nodes;
|
||||
std::unordered_set<NodeID> traffic_lights;
|
||||
TrafficSignals traffic_lights;
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations;
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
@ -259,7 +259,7 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity)
|
||||
BOOST_AUTO_TEST_CASE(skip_degree_two_nodes)
|
||||
{
|
||||
std::unordered_set<NodeID> barrier_nodes{1};
|
||||
std::unordered_set<NodeID> traffic_lights{2};
|
||||
TrafficSignals traffic_lights = {{2}, {}};
|
||||
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||
std::vector<TurnRestriction> restrictions;
|
||||
CompressedEdgeContainer container;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user