Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9912b26b32 | |||
| 838b2a750e |
+10
-9
@@ -15,6 +15,7 @@ branches:
|
||||
- master
|
||||
# enable building tags
|
||||
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||
- 5.12
|
||||
|
||||
cache:
|
||||
yarn: true
|
||||
@@ -68,7 +69,7 @@ matrix:
|
||||
addons: &gcc6
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' ENABLE_COVERAGE=ON CUCUMBER_TIMEOUT=20000
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
@@ -78,7 +79,7 @@ matrix:
|
||||
addons: &gcc6
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' TARGET_ARCH='x86_64-asan' ENABLE_SANITIZER=ON CUCUMBER_TIMEOUT=20000
|
||||
|
||||
- os: linux
|
||||
@@ -86,7 +87,7 @@ matrix:
|
||||
addons: &clang40
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-5-dev', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
packages: ['libstdc++-5-dev', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' CUCUMBER_TIMEOUT=60000
|
||||
|
||||
- os: linux
|
||||
@@ -111,7 +112,7 @@ matrix:
|
||||
addons: &gcc6
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
@@ -125,7 +126,7 @@ matrix:
|
||||
addons: &gcc6
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libstxxl-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libstxxl-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' ENABLE_STXXL=On
|
||||
|
||||
- os: linux
|
||||
@@ -133,7 +134,7 @@ matrix:
|
||||
addons: &gcc49
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.9', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev', 'ccache']
|
||||
packages: ['g++-4.9', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-4.9' CXXCOMPILER='g++-4.9' BUILD_TYPE='Release'
|
||||
|
||||
- os: osx
|
||||
@@ -158,7 +159,7 @@ matrix:
|
||||
#- addons: &clang40
|
||||
#- apt:
|
||||
#- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test']
|
||||
#- packages: ['clang-4.0', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
#- packages: ['clang-4.0', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
#- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release'
|
||||
|
||||
# Shared Library
|
||||
@@ -167,7 +168,7 @@ matrix:
|
||||
addons: &gcc6
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
# Disabled because CI slowness
|
||||
@@ -176,7 +177,7 @@ matrix:
|
||||
#- addons: &clang40
|
||||
#- apt:
|
||||
#- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test']
|
||||
#- packages: ['clang-4.0', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
#- packages: ['clang-4.0', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
#- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
# Node build jobs. These skip running the tests.
|
||||
|
||||
+1
-10
@@ -1,14 +1,5 @@
|
||||
# UNRELEASED
|
||||
- Profile:
|
||||
- New function to support relations: `process_relation`. Read more in profiles documentation.
|
||||
- Append cardinal directions from route relations to ref fields to improve instructions
|
||||
- Support of `distance` weight in foot and bicycle profiles
|
||||
- Infrastructure:
|
||||
- Lua 5.1 support is removed due to lack of support in sol2 https://github.com/ThePhD/sol2/issues/302
|
||||
- Node.js Bindings:
|
||||
- Exposes `use_threads_number=Number` parameter of `EngineConfig` to limit a number of threads in a TBB internal pool
|
||||
|
||||
# 5.12.0
|
||||
- Changes from 5.11.0
|
||||
- Guidance
|
||||
- now announcing turning onto oneways at the end of a road (e.g. onto dual carriageways)
|
||||
- Adds new instruction types at the exit of roundabouts and rotaries `exit roundabout` and `exit rotary`.
|
||||
|
||||
+21
-4
@@ -60,7 +60,7 @@ if (POLICY CMP0048)
|
||||
endif()
|
||||
project(OSRM C CXX)
|
||||
set(OSRM_VERSION_MAJOR 5)
|
||||
set(OSRM_VERSION_MINOR 13)
|
||||
set(OSRM_VERSION_MINOR 12)
|
||||
set(OSRM_VERSION_PATCH 0)
|
||||
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
|
||||
|
||||
@@ -379,8 +379,8 @@ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
|
||||
|
||||
# Activate C++1y
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
|
||||
set(OSRM_CXXFLAGS "${OSRM_CXXFLAGS} -std=c++14")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")
|
||||
set(OSRM_CXXFLAGS "${OSRM_CXXFLAGS} -std=c++1y")
|
||||
endif()
|
||||
|
||||
# Configuring other platform dependencies
|
||||
@@ -521,7 +521,24 @@ else()
|
||||
IF (LUA_FOUND)
|
||||
MESSAGE(STATUS "Using Lua ${LUA_VERSION_STRING}")
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Lua 5.2 was not found.")
|
||||
FIND_PACKAGE(Lua 5.1 EXACT)
|
||||
IF (LUA_FOUND)
|
||||
MESSAGE(STATUS "Using Lua ${LUA_VERSION_STRING}")
|
||||
ELSE()
|
||||
# Now fall back to a lua verison without exact
|
||||
# in case this cmake version also forces patch versions
|
||||
FIND_PACKAGE(Lua 5.2)
|
||||
IF (LUA_FOUND)
|
||||
MESSAGE(STATUS "Using Lua ${LUA_VERSION_STRING}")
|
||||
ELSE()
|
||||
FIND_PACKAGE(Lua 5.1)
|
||||
IF (LUA_FOUND)
|
||||
MESSAGE(STATUS "Using Lua ${LUA_VERSION_STRING}")
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Lua 5.1 or 5.2 was not found.")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
set(USED_LUA_LIBRARIES ${LUA_LIBRARIES})
|
||||
|
||||
+4
-7
@@ -7,22 +7,19 @@ ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
SET PROJECT_DIR=%CD%
|
||||
ECHO PROJECT_DIR^: %PROJECT_DIR%
|
||||
ECHO NUMBER_OF_PROCESSORS^: %NUMBER_OF_PROCESSORS%
|
||||
|
||||
|
||||
:: Check CMake version
|
||||
SET CMAKE_VERSION=3.9.2
|
||||
SET PATH=%PROJECT_DIR%\cmake-%CMAKE_VERSION%-win32-x86\bin;%PATH%
|
||||
ECHO cmake^: && cmake --version
|
||||
IF %ERRORLEVEL% NEQ 0 ECHO CMAKE not found && GOTO CMAKE_NOT_OK
|
||||
|
||||
cmake --version | findstr /C:%CMAKE_VERSION% && GOTO CMAKE_OK
|
||||
cmake --version | findstr /C:"3.7.1" && GOTO CMAKE_OK
|
||||
|
||||
:CMAKE_NOT_OK
|
||||
SET CMAKE_VERSION=3.7.1
|
||||
ECHO CMAKE NOT OK - downloading new CMake %CMAKE_VERSION%
|
||||
powershell Invoke-WebRequest https://cmake.org/files/v3.9/cmake-%CMAKE_VERSION%-win32-x86.zip -OutFile $env:PROJECT_DIR\cm.zip
|
||||
IF NOT EXIST cm.zip powershell Invoke-WebRequest https://cmake.org/files/v3.7/cmake-%CMAKE_VERSION%-win32-x86.zip -OutFile $env:PROJECT_DIR\cm.zip
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
IF NOT EXIST cmake-%CMAKE_VERSION%-win32-x86 7z -y x cm.zip | %windir%\system32\FIND "ing archive"
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
SET PATH=%PROJECT_DIR%\cmake-%CMAKE_VERSION%-win32-x86\bin;%PATH%
|
||||
|
||||
:CMAKE_OK
|
||||
ECHO CMAKE_OK
|
||||
|
||||
+7
-59
@@ -47,7 +47,7 @@ Profiles can also define a `process_segment` function to handle differences in s
|
||||
|
||||
At the end of the file, a table if returned with references to the setup and processing functions the profile has defined.
|
||||
|
||||
## Understanding speed, weight and rate
|
||||
## Understanding speed, weight and rate
|
||||
When computing a route from A to B there can be different measure of what is the best route. That's why there's a need for different profiles.
|
||||
|
||||
Because speeds very on different types of roads, the shortest and the fastest route are typically different. But there are many other possible preferences. For example a user might prefer a bicycle route that follow parks or other green areas, even though both duration and distance are a bit longer.
|
||||
@@ -91,7 +91,7 @@ The `setup` function is called once when the profile is loaded and must return a
|
||||
|
||||
Note that processing of data is parallelized and several unconnected LUA interpreters will be running at the same time. The `setup` function will be called once for each. Each LUA iinterpreter will have it's own set of globals.
|
||||
|
||||
The following global properties can be set under `properties` in the hash you return in the `setup` function:
|
||||
The following global properties can be set under `properties` in the hash you return in the `setup` function:
|
||||
|
||||
Attribute | Type | Notes
|
||||
-------------------------------------|----------|----------------------------------------------------------------------------
|
||||
@@ -114,7 +114,7 @@ classes | Sequence | Determines the allowed
|
||||
restrictions | Sequence | Determines which turn restrictions will be used for this profile.
|
||||
suffix_list | Set | List of name suffixes needed for determining if "Highway 101 NW" the same road as "Highway 101 ES".
|
||||
|
||||
### process_node(profile, node, result, relations)
|
||||
### process_node(profile, node, result)
|
||||
Process an OSM node to determine whether this node is a barrier or can be passed and whether passing it incurs a delay.
|
||||
|
||||
Argument | Description
|
||||
@@ -122,7 +122,6 @@ Argument | Description
|
||||
profile | The configuration table you returned in `setup`.
|
||||
node | The input node to process (read-only).
|
||||
result | The output that you will modify.
|
||||
relations| The list of relation attributes passed from `process_relation` function for this node.
|
||||
|
||||
The following attributes can be set on `result`:
|
||||
|
||||
@@ -131,7 +130,7 @@ Attribute | Type | Notes
|
||||
barrier | Boolean | Is it an impassable barrier?
|
||||
traffic_lights | Boolean | Is it a traffic light (incurs delay in `process_turn`)?
|
||||
|
||||
### process_way(profile, way, result, relations)
|
||||
## process_way(profile, way, result)
|
||||
Given an OpenStreetMap way, the `process_way` function will either return nothing (meaning we are not going to route over this way at all), or it will set up a result hash.
|
||||
|
||||
Argument | Description
|
||||
@@ -139,7 +138,6 @@ Argument | Description
|
||||
profile | The configuration table you returned in `setup`.
|
||||
node | The input way to process (read-only).
|
||||
result | The output that you will modify.
|
||||
relations| The list of relation attributes passed from `process_relation` function for this way.
|
||||
|
||||
Importantly it will set `result.forward_mode` and `result.backward_mode` to indicate the travel mode in each direction, as well as set `result.forward_speed` and `result.backward_speed` to integer values representing the speed for traversing the way.
|
||||
|
||||
@@ -179,60 +177,10 @@ road_classification.road_priority_class | Enum | Guidance: order in priority
|
||||
road_classification.may_be_ignored | Boolean | Guidance: way is non-highway
|
||||
road_classification.num_lanes | Unsigned | Guidance: total number of lanes in way
|
||||
|
||||
### process_relation(profile, relation, result)
|
||||
|
||||
Supported since API **version 3**.
|
||||
|
||||
Given an OpenStreetMap relation, the `process_relation` function should setup values into result structure.
|
||||
|
||||
Argument | Description
|
||||
---------|-------------------------------------------------------
|
||||
profile | The configuration table you returned in `setup`.
|
||||
node | The input relation to process (read-only).
|
||||
result | The output that you will modify.
|
||||
|
||||
Relation process work flow consist of next steps:
|
||||
1. Calls `process_relation` function for each relation. It should fill a `result` structure
|
||||
2. After that each data will be passed for each member of processed relation into `process_node` and `process_way` functions
|
||||
|
||||
The following attributes can be set on that result in `process_relation`:
|
||||
|
||||
Attribute | Type | Notes
|
||||
----------------------------------------|----------|--------------------------------------------------------------------------
|
||||
is_restriction | Boolean | Flag to determine if relation is a turn restriction
|
||||
|
||||
Example processing code:
|
||||
```lua
|
||||
|
||||
function process_way(profile, way, result, relations)
|
||||
for _, r in ipairs(relations) do
|
||||
for k, v in pairs(r) do
|
||||
print('data_' .. k .. '_value_' .. v)
|
||||
end
|
||||
end
|
||||
print ('process_way ' .. way:id() .. ' ' .. result.name)
|
||||
end
|
||||
|
||||
function process_relation(profile, relation, result)
|
||||
local t = relation:get_value_by_key("type")
|
||||
if t == "route" then
|
||||
for _, m in ipairs(relation:members()) do
|
||||
if m:role == "north" then
|
||||
result[m]['direction'] = 'north'
|
||||
print('direction_north')
|
||||
end
|
||||
end
|
||||
|
||||
print('route_relation')
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
### process_segment(profile, segment)
|
||||
The `process_segment` function is called for every segment of OSM ways. A segment is a straight line between two OSM nodes.
|
||||
The `process_segment` function is called for every segment of OSM ways. A segment is a straight line between two OSM nodes.
|
||||
|
||||
On OpenStreetMap way cannot have different tags on different parts of a way. Instead you would split the way into several smaller ways. However many ways are long. For example, many ways pass hills without any change in tags.
|
||||
On OpenStreetMap way cannot have different tags on different parts of a way. Instead you would split the way into several smaller ways. However many ways are long. For example, many ways pass hills without any change in tags.
|
||||
|
||||
Processing each segment of an OSM way makes it possible to have different speeds on different parts of a way based on external data like data about elevation, pollution, noise or scenic value and adjust weight and duration of the segment.
|
||||
|
||||
@@ -317,7 +265,7 @@ Example:
|
||||
function process_segment (profile, segment)
|
||||
local sourceData = raster:query(profile.raster_source, segment.source.lon, segment.source.lat)
|
||||
local targetData = raster:query(profile.raster_source, segment.target.lon, segment.target.lat)
|
||||
|
||||
|
||||
local invalid = sourceData.invalid_data()
|
||||
if sourceData.datum ~= invalid and targetData.datum ~= invalid then
|
||||
-- use values to adjust weight and duration
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
@routing @bicycle
|
||||
Feature: Bike - Use distance weight
|
||||
|
||||
Background:
|
||||
Given a grid size of 200 meters
|
||||
|
||||
Scenario: Bike - Check distance weight
|
||||
Given the profile file
|
||||
"""
|
||||
local functions = require('bicycle')
|
||||
functions.setup_testbot = functions.setup
|
||||
|
||||
functions.setup = function()
|
||||
local profile = functions.setup_testbot()
|
||||
profile.properties.weight_name = 'distance'
|
||||
return profile
|
||||
end
|
||||
|
||||
return functions
|
||||
"""
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a-b-c
|
||||
"""
|
||||
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | residential |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | weight | time | distance |
|
||||
| a | b | abc,abc | 200 | 48s | 200m +-1 |
|
||||
| a | c | abc,abc | 400 | 96s | 400m +-1 |
|
||||
@@ -1,68 +0,0 @@
|
||||
@routing @car @relations
|
||||
Feature: Car - route relations
|
||||
Background:
|
||||
Given the profile "car"
|
||||
|
||||
@sliproads
|
||||
Scenario: Cardinal direction assignment to refs
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
| |
|
||||
c------+--+------d
|
||||
e------+--+------f
|
||||
| |
|
||||
g h
|
||||
|
||||
i----------------j
|
||||
k----------------l
|
||||
|
||||
x----------------y
|
||||
z----------------w
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | ref |
|
||||
| ag | southbound | motorway | I 80 |
|
||||
| hb | northbound | motorway | I 80 |
|
||||
| dc | westbound | motorway | I 85;CO 93 |
|
||||
| ef | eastbound | motorway | I 85;US 12 |
|
||||
| ij | westbound-2 | motorway | I 99 |
|
||||
| ji | eastbound-2 | motorway | I 99 |
|
||||
| kl | eastbound-2 | motorway | I 99 |
|
||||
| lk | eastbound-2 | motorway | I 99 |
|
||||
| xy | watermill | motorway | I 45M; US 3 |
|
||||
|
||||
And the relations
|
||||
| type | way:south | route | ref |
|
||||
| route | ag | road | 80 |
|
||||
| route | ef | road | 12 |
|
||||
|
||||
And the relations
|
||||
| type | way:north | route | ref |
|
||||
| route | hb | road | 80 |
|
||||
| route | cd | road | 93 |
|
||||
|
||||
And the relations
|
||||
| type | way:west | route | ref |
|
||||
| route | dc | road | 85 |
|
||||
| route | ij | road | 99 |
|
||||
| route | xy | road | I 45 |
|
||||
|
||||
And the relations
|
||||
| type | way:east | route | ref |
|
||||
| route | lk | road | I 99 |
|
||||
|
||||
And the relations
|
||||
| type | way:east | route | ref |
|
||||
| route | xy | road | US 3 |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | ref |
|
||||
| a,g | southbound,southbound | I 80 $south,I 80 $south |
|
||||
| h,b | northbound,northbound | I 80 $north,I 80 $north |
|
||||
| d,c | westbound,westbound | I 85 $west; CO 93 $north,I 85 $west; CO 93 $north |
|
||||
| e,f | eastbound,eastbound | I 85; US 12 $south,I 85; US 12 $south |
|
||||
| i,j | westbound-2,westbound-2 | I 99 $west,I 99 $west |
|
||||
| l,k | eastbound-2,eastbound-2 | I 99 $east,I 99 $east |
|
||||
| x,y | watermill,watermill | I 45M $west; US 3 $east,I 45M $west; US 3 $east |
|
||||
@@ -1,35 +0,0 @@
|
||||
@routing @foot
|
||||
Feature: Foot - Use distance weight
|
||||
|
||||
Background:
|
||||
Given a grid size of 200 meters
|
||||
|
||||
Scenario: Foot - Check distance weight
|
||||
Given the profile file
|
||||
"""
|
||||
local functions = require('foot')
|
||||
functions.setup_testbot = functions.setup
|
||||
|
||||
functions.setup = function()
|
||||
local profile = functions.setup_testbot()
|
||||
profile.properties.weight_name = 'distance'
|
||||
return profile
|
||||
end
|
||||
|
||||
return functions
|
||||
"""
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a-b-c
|
||||
"""
|
||||
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | residential |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | weight | time | distance |
|
||||
| a | b | abc,abc | 200 | 144s | 200m +-1 |
|
||||
| a | c | abc,abc | 400 | 288s | 400m +-1 |
|
||||
@@ -1349,24 +1349,3 @@ Feature: Simple Turns
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | ab,dc,dc | depart,turn left,arrive |
|
||||
|
||||
|
||||
# https://www.openstreetmap.org/node/1332083066
|
||||
Scenario: Turns ordering must respect initial bearings
|
||||
Given the node map
|
||||
"""
|
||||
a . be .
|
||||
\ c.
|
||||
d/ .f . g
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway |
|
||||
| ab | primary | yes |
|
||||
| bcd | primary | yes |
|
||||
| befg | primary | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | ab,bcd,bcd | depart,fork slight right,arrive |
|
||||
| a,g | ab,befg,befg | depart,fork slight left,arrive |
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
@extract
|
||||
Feature: osrm-extract must be silent with NONE
|
||||
|
||||
Background:
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
"""
|
||||
And the ways
|
||||
| nodes |
|
||||
| ab |
|
||||
And the data has been saved to disk
|
||||
|
||||
Scenario: osrm-extract - Passing base file with verbosity NONE
|
||||
Given the profile file
|
||||
"""
|
||||
functions = require('testbot')
|
||||
|
||||
function way_function(profile, way, result)
|
||||
result.forward_mode = mode.driving
|
||||
result.forward_speed = 1
|
||||
end
|
||||
|
||||
functions.process_way = way_function
|
||||
return functions
|
||||
"""
|
||||
When I run "osrm-extract --profile {profile_file} {osm_file} --verbosity NONE"
|
||||
Then it should exit successfully
|
||||
And stdout should not contain "[info]"
|
||||
And stdout should not contain "[error]"
|
||||
And stdout should not contain "10%"
|
||||
And stderr should be empty
|
||||
@@ -24,7 +24,7 @@ Feature: Invalid profile API versions
|
||||
Scenario: Profile API version too high
|
||||
Given the profile file
|
||||
"""
|
||||
api_version = 4
|
||||
api_version = 3
|
||||
"""
|
||||
And the node map
|
||||
"""
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
Feature: Profile API version 3
|
||||
|
||||
Background:
|
||||
Given a grid size of 100 meters
|
||||
|
||||
Scenario: Basic profile function calls and property values
|
||||
Given the profile file
|
||||
"""
|
||||
api_version = 3
|
||||
|
||||
Set = require('lib/set')
|
||||
Sequence = require('lib/sequence')
|
||||
Handlers = require("lib/way_handlers")
|
||||
find_access_tag = require("lib/access").find_access_tag
|
||||
limit = require("lib/maxspeed").limit
|
||||
|
||||
|
||||
function setup()
|
||||
return {
|
||||
properties = {
|
||||
max_speed_for_map_matching = 180/3.6,
|
||||
use_turn_restrictions = true,
|
||||
continue_straight_at_waypoint = true,
|
||||
weight_name = 'test_version2',
|
||||
weight_precision = 2
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function process_node(profile, node, result, relations)
|
||||
print ('process_node ' .. node:id())
|
||||
end
|
||||
|
||||
function process_way(profile, way, result, relations)
|
||||
result.name = way:get_value_by_key('name')
|
||||
result.weight = 10
|
||||
result.forward_mode = mode.driving
|
||||
result.backward_mode = mode.driving
|
||||
result.forward_speed = 36
|
||||
result.backward_speed = 36
|
||||
|
||||
for _, r in ipairs(relations) do
|
||||
for k, v in pairs(r) do
|
||||
print('data_' .. k .. '_value_' .. v)
|
||||
end
|
||||
end
|
||||
print ('process_way ' .. way:id() .. ' ' .. result.name)
|
||||
end
|
||||
|
||||
function process_relation(profile, relation, result)
|
||||
local t = relation:get_value_by_key("type")
|
||||
if t == "route" then
|
||||
for _, m in ipairs(relation:members()) do
|
||||
if m:role() == "north" then
|
||||
result[m]['direction'] = 'north'
|
||||
print('direction_north')
|
||||
end
|
||||
end
|
||||
|
||||
print('route_relation')
|
||||
end
|
||||
|
||||
print ('process_relation ' .. relation:id())
|
||||
end
|
||||
|
||||
function process_turn (profile, turn)
|
||||
print('process_turn', turn.angle, turn.turn_type, turn.direction_modifier, turn.has_traffic_light)
|
||||
turn.weight = turn.angle == 0 and 0 or 4.2
|
||||
turn.duration = turn.weight
|
||||
end
|
||||
|
||||
function process_segment (profile, segment)
|
||||
print ('process_segment ' .. segment.source.lon .. ' ' .. segment.source.lat)
|
||||
end
|
||||
|
||||
return {
|
||||
setup = setup,
|
||||
process_node = process_node,
|
||||
process_way = process_way,
|
||||
process_relation = process_relation,
|
||||
process_segment = process_segment,
|
||||
process_turn = process_turn
|
||||
}
|
||||
"""
|
||||
And the node map
|
||||
"""
|
||||
a
|
||||
bcd
|
||||
e
|
||||
"""
|
||||
And the ways
|
||||
| nodes |
|
||||
| ac |
|
||||
| cb |
|
||||
| cd |
|
||||
| ce |
|
||||
|
||||
And the relations
|
||||
| type | way:north | route |
|
||||
| route | ac | road |
|
||||
|
||||
And the data has been saved to disk
|
||||
|
||||
When I run "osrm-extract --profile {profile_file} {osm_file}"
|
||||
Then it should exit successfully
|
||||
And stdout should contain "process_relation"
|
||||
And stdout should contain "route_relation"
|
||||
And stdout should contain "direction_north"
|
||||
And stdout should contain "data_direction_value_north"
|
||||
And stdout should contain "process_node"
|
||||
And stdout should contain "process_way"
|
||||
And stdout should contain "process_turn"
|
||||
And stdout should contain "process_segment"
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| a | b | ac,cb,cb | 19.2s |
|
||||
| a | d | ac,cd,cd | 19.2s |
|
||||
| a | e | ac,ce | 20s |
|
||||
@@ -24,8 +24,6 @@
|
||||
#include "util/fingerprint.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
#include <tbb/task_scheduler_init.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@@ -55,8 +53,7 @@ template <typename Algorithm> class Engine final : public EngineInterface
|
||||
{
|
||||
public:
|
||||
explicit Engine(const EngineConfig &config)
|
||||
: task_scheduler(config.use_threads_number),
|
||||
route_plugin(config.max_locations_viaroute, config.max_alternatives), //
|
||||
: route_plugin(config.max_locations_viaroute, config.max_alternatives), //
|
||||
table_plugin(config.max_locations_distance_table), //
|
||||
nearest_plugin(config.max_results_nearest), //
|
||||
trip_plugin(config.max_locations_trip), //
|
||||
@@ -128,7 +125,6 @@ template <typename Algorithm> class Engine final : public EngineInterface
|
||||
}
|
||||
std::unique_ptr<DataFacadeProvider<Algorithm>> facade_provider;
|
||||
mutable SearchEngineData<Algorithm> heaps;
|
||||
tbb::task_scheduler_init task_scheduler;
|
||||
|
||||
const plugins::ViaRoutePlugin route_plugin;
|
||||
const plugins::TablePlugin table_plugin;
|
||||
|
||||
@@ -90,8 +90,6 @@ struct EngineConfig final
|
||||
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
||||
bool use_shared_memory = true;
|
||||
Algorithm algorithm = Algorithm::CH;
|
||||
int use_threads_number = 1;
|
||||
std::string verbosity;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ template <typename Algorithm>
|
||||
std::vector<EdgeWeight> manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::vector<std::size_t> source_indices,
|
||||
std::vector<std::size_t> target_indices);
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices);
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
#ifndef EXTRACTION_RELATION_HPP
|
||||
#define EXTRACTION_RELATION_HPP
|
||||
|
||||
#include <osmium/osm/relation.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
struct ExtractionRelation
|
||||
{
|
||||
using AttributesMap = std::unordered_map<std::string, std::string>;
|
||||
using OsmIDTyped = std::pair<osmium::object_id_type, osmium::item_type>;
|
||||
|
||||
struct OsmIDTypedHash
|
||||
{
|
||||
std::size_t operator()(const OsmIDTyped &id) const
|
||||
{
|
||||
return id.first ^ (static_cast<std::uint64_t>(id.second) << 56);
|
||||
}
|
||||
};
|
||||
|
||||
ExtractionRelation() : is_restriction(false) {}
|
||||
|
||||
void clear()
|
||||
{
|
||||
is_restriction = false;
|
||||
values.clear();
|
||||
}
|
||||
|
||||
bool IsRestriction() const { return is_restriction; }
|
||||
|
||||
AttributesMap &GetMember(const osmium::RelationMember &member)
|
||||
{
|
||||
return values[OsmIDTyped(member.ref(), member.type())];
|
||||
}
|
||||
|
||||
bool is_restriction;
|
||||
std::unordered_map<OsmIDTyped, AttributesMap, OsmIDTypedHash> values;
|
||||
};
|
||||
|
||||
// It contains data of all parsed relations for each node/way element
|
||||
class ExtractionRelationContainer
|
||||
{
|
||||
public:
|
||||
using AttributesMap = ExtractionRelation::AttributesMap;
|
||||
using OsmIDTyped = ExtractionRelation::OsmIDTyped;
|
||||
using RelationList = std::vector<AttributesMap>;
|
||||
|
||||
void AddRelation(const ExtractionRelation &rel)
|
||||
{
|
||||
BOOST_ASSERT(!rel.is_restriction);
|
||||
for (auto it : rel.values)
|
||||
data[it.first].push_back(it.second);
|
||||
}
|
||||
|
||||
const RelationList &Get(const OsmIDTyped &id) const
|
||||
{
|
||||
const auto it = data.find(id);
|
||||
if (it != data.end())
|
||||
return it->second;
|
||||
|
||||
static RelationList empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<OsmIDTyped, RelationList, ExtractionRelation::OsmIDTypedHash> data;
|
||||
};
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // EXTRACTION_RELATION_HPP
|
||||
@@ -15,7 +15,6 @@ namespace osmium
|
||||
{
|
||||
class Node;
|
||||
class Way;
|
||||
class Relation;
|
||||
}
|
||||
|
||||
namespace std
|
||||
@@ -45,7 +44,6 @@ namespace extractor
|
||||
class ExtractionContainers;
|
||||
struct ExtractionNode;
|
||||
struct ExtractionWay;
|
||||
struct ExtractionRelation;
|
||||
struct ProfileProperties;
|
||||
struct InputConditionalTurnRestriction;
|
||||
|
||||
|
||||
@@ -153,14 +153,6 @@ class CoordinateExtractor
|
||||
const double length,
|
||||
const double rate) const;
|
||||
|
||||
// find the coordinate at a specific distance in the vector
|
||||
util::Coordinate
|
||||
ExtractCoordinateAtLength(const double distance,
|
||||
const std::vector<util::Coordinate> &coordinates) const;
|
||||
util::Coordinate ExtractCoordinateAtLength(const double distance,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const std::vector<double> &length_cache) const;
|
||||
|
||||
private:
|
||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||
const extractor::CompressedEdgeContainer &compressed_geometries;
|
||||
@@ -249,6 +241,14 @@ class CoordinateExtractor
|
||||
const double segment_length,
|
||||
const std::vector<double> &segment_distances,
|
||||
const std::uint8_t considered_lanes) const;
|
||||
|
||||
// find the coordinate at a specific location in the vector
|
||||
util::Coordinate ExtractCoordinateAtLength(const double distance,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const std::vector<double> &length_cache) const;
|
||||
util::Coordinate
|
||||
ExtractCoordinateAtLength(const double distance,
|
||||
const std::vector<util::Coordinate> &coordinates) const;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
|
||||
@@ -19,7 +19,6 @@ namespace osmium
|
||||
{
|
||||
class Node;
|
||||
class Way;
|
||||
class Relation;
|
||||
}
|
||||
|
||||
namespace osrm
|
||||
@@ -34,10 +33,8 @@ namespace extractor
|
||||
{
|
||||
|
||||
class RestrictionParser;
|
||||
class ExtractionRelationContainer;
|
||||
struct ExtractionNode;
|
||||
struct ExtractionWay;
|
||||
struct ExtractionRelation;
|
||||
struct ExtractionTurn;
|
||||
struct ExtractionSegment;
|
||||
|
||||
@@ -62,14 +59,12 @@ class ScriptingEnvironment
|
||||
virtual void ProcessTurn(ExtractionTurn &turn) = 0;
|
||||
virtual void ProcessSegment(ExtractionSegment &segment) = 0;
|
||||
|
||||
virtual void ProcessElements(
|
||||
const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
const ExtractionRelationContainer &relations,
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
||||
std::vector<std::pair<const osmium::Relation &, ExtractionRelation>> &resulting_relations,
|
||||
std::vector<InputConditionalTurnRestriction> &resulting_restrictions) = 0;
|
||||
virtual void
|
||||
ProcessElements(const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
||||
std::vector<InputConditionalTurnRestriction> &resulting_restrictions) = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef SCRIPTING_ENVIRONMENT_LUA_HPP
|
||||
#define SCRIPTING_ENVIRONMENT_LUA_HPP
|
||||
|
||||
#include "extractor/extraction_relation.hpp"
|
||||
#include "extractor/raster_source.hpp"
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
|
||||
@@ -20,13 +19,8 @@ namespace extractor
|
||||
|
||||
struct LuaScriptingContext final
|
||||
{
|
||||
void ProcessNode(const osmium::Node &,
|
||||
ExtractionNode &result,
|
||||
const ExtractionRelationContainer::RelationList &relations);
|
||||
void ProcessWay(const osmium::Way &,
|
||||
ExtractionWay &result,
|
||||
const ExtractionRelationContainer::RelationList &relations);
|
||||
void ProcessRelation(const osmium::Relation &, ExtractionRelation &result);
|
||||
void ProcessNode(const osmium::Node &, ExtractionNode &result);
|
||||
void ProcessWay(const osmium::Way &, ExtractionWay &result);
|
||||
|
||||
ProfileProperties properties;
|
||||
RasterContainer raster_sources;
|
||||
@@ -35,13 +29,11 @@ struct LuaScriptingContext final
|
||||
bool has_turn_penalty_function;
|
||||
bool has_node_function;
|
||||
bool has_way_function;
|
||||
bool has_relation_function;
|
||||
bool has_segment_function;
|
||||
|
||||
sol::function turn_function;
|
||||
sol::function way_function;
|
||||
sol::function node_function;
|
||||
sol::function relation_function;
|
||||
sol::function segment_function;
|
||||
|
||||
int api_version;
|
||||
@@ -59,7 +51,7 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
|
||||
{
|
||||
public:
|
||||
static const constexpr int SUPPORTED_MIN_API_VERSION = 0;
|
||||
static const constexpr int SUPPORTED_MAX_API_VERSION = 3;
|
||||
static const constexpr int SUPPORTED_MAX_API_VERSION = 2;
|
||||
|
||||
explicit Sol2ScriptingEnvironment(const std::string &file_name);
|
||||
~Sol2ScriptingEnvironment() override = default;
|
||||
@@ -73,14 +65,12 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
|
||||
void ProcessTurn(ExtractionTurn &turn) override;
|
||||
void ProcessSegment(ExtractionSegment &segment) override;
|
||||
|
||||
void ProcessElements(
|
||||
const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
const ExtractionRelationContainer &relations,
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
||||
std::vector<std::pair<const osmium::Relation &, ExtractionRelation>> &resulting_relations,
|
||||
std::vector<InputConditionalTurnRestriction> &resulting_restrictions) override;
|
||||
void
|
||||
ProcessElements(const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
||||
std::vector<InputConditionalTurnRestriction> &resulting_restrictions) override;
|
||||
|
||||
private:
|
||||
LuaScriptingContext &GetSol2Context();
|
||||
|
||||
@@ -186,7 +186,6 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
|
||||
params->Get(Nan::New("max_locations_map_matching").ToLocalChecked());
|
||||
auto max_results_nearest = params->Get(Nan::New("max_results_nearest").ToLocalChecked());
|
||||
auto max_alternatives = params->Get(Nan::New("max_alternatives").ToLocalChecked());
|
||||
auto use_threads_number = params->Get(Nan::New("use_threads_number").ToLocalChecked());
|
||||
|
||||
if (!max_locations_trip->IsUndefined() && !max_locations_trip->IsNumber())
|
||||
{
|
||||
@@ -218,11 +217,6 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
|
||||
Nan::ThrowError("max_alternatives must be an integral number");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
if (!use_threads_number->IsUndefined() && !use_threads_number->IsNumber())
|
||||
{
|
||||
Nan::ThrowError("use_threads_number must be an integral number");
|
||||
return engine_config_ptr();
|
||||
}
|
||||
|
||||
if (max_locations_trip->IsNumber())
|
||||
engine_config->max_locations_trip = static_cast<int>(max_locations_trip->NumberValue());
|
||||
@@ -239,8 +233,6 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
|
||||
engine_config->max_results_nearest = static_cast<int>(max_results_nearest->NumberValue());
|
||||
if (max_alternatives->IsNumber())
|
||||
engine_config->max_alternatives = static_cast<int>(max_alternatives->NumberValue());
|
||||
if (use_threads_number->IsNumber())
|
||||
engine_config->use_threads_number = static_cast<int>(use_threads_number->NumberValue());
|
||||
|
||||
return engine_config;
|
||||
}
|
||||
|
||||
+2
-32
@@ -53,40 +53,10 @@ class Log
|
||||
virtual ~Log();
|
||||
std::mutex &get_mutex();
|
||||
|
||||
template <typename T> inline Log &operator<<(const T &data)
|
||||
{
|
||||
const auto &policy = LogPolicy::GetInstance();
|
||||
if (!policy.IsMute() && level <= policy.GetLevel())
|
||||
{
|
||||
stream << data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T> inline Log &operator<<(const std::atomic<T> &data)
|
||||
{
|
||||
const auto &policy = LogPolicy::GetInstance();
|
||||
if (!policy.IsMute() && level <= policy.GetLevel())
|
||||
{
|
||||
stream << T(data);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef std::ostream &(manip)(std::ostream &);
|
||||
|
||||
inline Log &operator<<(manip &m)
|
||||
{
|
||||
const auto &policy = LogPolicy::GetInstance();
|
||||
if (!policy.IsMute() && level <= policy.GetLevel())
|
||||
{
|
||||
stream << m;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T> inline std::ostream &operator<<(const T &data) { return stream << data; }
|
||||
|
||||
protected:
|
||||
const LogLevel level;
|
||||
LogLevel level;
|
||||
std::ostringstream buffer;
|
||||
std::ostream &stream;
|
||||
};
|
||||
|
||||
@@ -83,7 +83,7 @@ class Percent
|
||||
// When not on a TTY, print newlines after each progress indicator so
|
||||
// so that progress is visible to line-buffered logging systems
|
||||
if (!IsStdoutATTY())
|
||||
log << std::endl;
|
||||
log << "" << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "osrm",
|
||||
"version": "5.13.0-cardinal.1",
|
||||
"version": "5.12.0",
|
||||
"private": false,
|
||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
||||
"dependencies": {
|
||||
|
||||
@@ -536,7 +536,7 @@ function process_way(profile, way, result)
|
||||
|
||||
-- handle turn lanes and road classification, used for guidance
|
||||
WayHandlers.classification,
|
||||
|
||||
|
||||
-- handle allowed start/end modes
|
||||
WayHandlers.startpoint,
|
||||
|
||||
@@ -544,10 +544,7 @@ function process_way(profile, way, result)
|
||||
WayHandlers.roundabouts,
|
||||
|
||||
-- set name, ref and pronunciation
|
||||
WayHandlers.names,
|
||||
|
||||
-- set weight properties of the way
|
||||
WayHandlers.weights
|
||||
WayHandlers.names
|
||||
}
|
||||
|
||||
WayHandlers.run(profile,way,result,data,handlers)
|
||||
|
||||
+3
-75
@@ -1,14 +1,12 @@
|
||||
-- Car profile
|
||||
|
||||
api_version = 3
|
||||
api_version = 2
|
||||
|
||||
Set = require('lib/set')
|
||||
Sequence = require('lib/sequence')
|
||||
Handlers = require("lib/way_handlers")
|
||||
Relations = require("lib/relations")
|
||||
find_access_tag = require("lib/access").find_access_tag
|
||||
limit = require("lib/maxspeed").limit
|
||||
Utils = require("lib/utils")
|
||||
|
||||
function setup()
|
||||
local use_left_hand_driving = false
|
||||
@@ -256,7 +254,6 @@ function setup()
|
||||
["ch:trunk"] = 100,
|
||||
["ch:motorway"] = 120,
|
||||
["de:living_street"] = 7,
|
||||
["dk:rural"] = 80,
|
||||
["ru:living_street"] = 20,
|
||||
["ru:urban"] = 60,
|
||||
["ua:urban"] = 60,
|
||||
@@ -281,7 +278,7 @@ function setup()
|
||||
}
|
||||
end
|
||||
|
||||
function process_node(profile, node, result, relations)
|
||||
function process_node(profile, node, result)
|
||||
-- parse access and barrier tags
|
||||
local access = find_access_tag(node, profile.access_tags_hierarchy)
|
||||
if access then
|
||||
@@ -308,7 +305,7 @@ function process_node(profile, node, result, relations)
|
||||
end
|
||||
end
|
||||
|
||||
function process_way(profile, way, result, relations)
|
||||
function process_way(profile, way, result)
|
||||
-- the intial filtering of ways based on presence of tags
|
||||
-- affects processing times significantly, because all ways
|
||||
-- have to be checked.
|
||||
@@ -392,74 +389,6 @@ function process_way(profile, way, result, relations)
|
||||
}
|
||||
|
||||
WayHandlers.run(profile,way,result,data,handlers)
|
||||
|
||||
-- now process relations data
|
||||
local matched_refs = nil;
|
||||
if result.ref then
|
||||
local match_res = Relations.match_to_ref(relations, result.ref)
|
||||
|
||||
local ref = ''
|
||||
for _, m in pairs(match_res) do
|
||||
if ref ~= '' then
|
||||
ref = ref .. '; '
|
||||
end
|
||||
|
||||
if m.dir then
|
||||
ref = ref .. m.ref .. ' $' .. m.dir
|
||||
else
|
||||
ref = ref .. m.ref
|
||||
end
|
||||
end
|
||||
|
||||
result.ref = ref
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function process_relation(profile, relation, result)
|
||||
local t = relation:get_value_by_key("type")
|
||||
|
||||
function add_extra_data(m)
|
||||
local name = relation:get_value_by_key("name")
|
||||
if name then
|
||||
result[m]['route_name'] = name
|
||||
end
|
||||
|
||||
local ref = relation:get_value_by_key("ref")
|
||||
if ref then
|
||||
result[m]['route_ref'] = ref
|
||||
end
|
||||
end
|
||||
|
||||
if t == 'route' then
|
||||
local route = relation:get_value_by_key("route")
|
||||
if route == 'road' then
|
||||
for _, m in ipairs(relation:members()) do
|
||||
-- process case, where directions set as role
|
||||
local role = string.lower(m:role())
|
||||
if role == 'north' or role == 'south' or role == 'west' or role == 'east' then
|
||||
result[m]['route_direction'] = role
|
||||
add_extra_data(m)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local direction = relation:get_value_by_key('direction')
|
||||
if direction then
|
||||
direction = string.lower(direction)
|
||||
if direction == 'north' or direction == 'south' or direction == 'west' or direction == 'east' then
|
||||
for _, m in ipairs(relation:members()) do
|
||||
if m:role() == 'forward' then
|
||||
result[m]['route_direction'] = direction
|
||||
add_extra_data(m)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
function process_turn(profile, turn)
|
||||
@@ -504,6 +433,5 @@ return {
|
||||
setup = setup,
|
||||
process_way = process_way,
|
||||
process_node = process_node,
|
||||
process_relation = process_relation,
|
||||
process_turn = process_turn
|
||||
}
|
||||
|
||||
+1
-4
@@ -237,10 +237,7 @@ function process_way(profile, way, result)
|
||||
WayHandlers.startpoint,
|
||||
|
||||
-- set name, ref and pronunciation
|
||||
WayHandlers.names,
|
||||
|
||||
-- set weight properties of the way
|
||||
WayHandlers.weights
|
||||
WayHandlers.names
|
||||
}
|
||||
|
||||
WayHandlers.run(profile,way,result,data,handlers)
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
-- Profile functions dealing with various aspects of relation parsing
|
||||
--
|
||||
-- You can run a selection you find useful in your profile,
|
||||
-- or do you own processing if/when required.
|
||||
|
||||
Utils = require('lib/utils')
|
||||
|
||||
Relations = {}
|
||||
|
||||
-- match ref values to relations data
|
||||
function Relations.match_to_ref(relations, ref)
|
||||
|
||||
function calculate_scores(refs, tag_value)
|
||||
local tag_tokens = Set(Utils.tokenize_common(tag_value))
|
||||
local result = {}
|
||||
for i, r in ipairs(refs) do
|
||||
local ref_tokens = Utils.tokenize_common(r)
|
||||
local score = 0
|
||||
|
||||
for _, t in ipairs(ref_tokens) do
|
||||
if tag_tokens[t] then
|
||||
if Utils.is_number(t) then
|
||||
score = score + 2
|
||||
else
|
||||
score = score + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
result[r] = score
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
local references = Utils.string_list_tokens(ref)
|
||||
local result_match = {}
|
||||
local order = {}
|
||||
for i, r in ipairs(references) do
|
||||
result_match[r] = false
|
||||
order[i] = r
|
||||
end
|
||||
|
||||
for i, rel in ipairs(relations) do
|
||||
local name_scores = nil
|
||||
local name_tokens = {}
|
||||
local route_name = rel["route_name"]
|
||||
if route_name then
|
||||
name_scores = calculate_scores(references, route_name)
|
||||
end
|
||||
|
||||
local ref_scores = nil
|
||||
local ref_tokens = {}
|
||||
local route_ref = rel["route_ref"]
|
||||
if route_ref then
|
||||
ref_scores = calculate_scores(references, route_ref)
|
||||
end
|
||||
|
||||
-- merge scores
|
||||
local direction = rel["route_direction"]
|
||||
if direction then
|
||||
local best_score = -1
|
||||
local best_ref = nil
|
||||
|
||||
function find_best(scores)
|
||||
if scores then
|
||||
for k ,v in pairs(scores) do
|
||||
if v > best_score then
|
||||
best_ref = k
|
||||
best_score = v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
find_best(name_scores)
|
||||
find_best(ref_scores)
|
||||
|
||||
if best_ref then
|
||||
result_match[best_ref] = direction
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local result = {}
|
||||
for i, r in ipairs(order) do
|
||||
result[i] = { ref = r, dir = result_match[r] };
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
return Relations
|
||||
@@ -1,43 +0,0 @@
|
||||
-- Profile functions to implement common algorithms of data processing
|
||||
--
|
||||
-- You can run a selection you find useful in your profile,
|
||||
-- or do you own processing if/when required.
|
||||
|
||||
Utils = {}
|
||||
|
||||
-- split string 'a; b; c' to table with values ['a', 'b', 'c']
|
||||
-- so it use just one separator ';'
|
||||
function Utils.string_list_tokens(str)
|
||||
result = {}
|
||||
local idx = 0
|
||||
for s in str.gmatch(str, "([^;]*)") do
|
||||
if s ~= nil and s ~= '' then
|
||||
idx = idx + 1
|
||||
result[idx] = s:gsub("^%s*(.-)%s*$", "%1")
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
-- same as Utils.StringListTokens, but with many possible separators:
|
||||
-- ',' | ';' | ' '| '(' | ')'
|
||||
function Utils.tokenize_common(str)
|
||||
result = {}
|
||||
local idx = 0
|
||||
for s in str.gmatch(str, "%S+") do
|
||||
if s ~= nil and s ~= '' then
|
||||
idx = idx + 1
|
||||
result[idx] = s:gsub("^%s*(.-)%s*$", "%1")
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
-- returns true, if string contains a number
|
||||
function Utils.is_number(str)
|
||||
return (tonumber(str) ~= nil)
|
||||
end
|
||||
|
||||
return Utils
|
||||
@@ -20,7 +20,7 @@ bool EngineConfig::IsValid() const
|
||||
unlimited_or_more_than(max_locations_trip, 2) &&
|
||||
unlimited_or_more_than(max_locations_viaroute, 2) &&
|
||||
unlimited_or_more_than(max_results_nearest, 0) &&
|
||||
max_alternatives >= 0 && use_threads_number >= 1;
|
||||
max_alternatives >= 0;
|
||||
|
||||
return ((use_shared_memory && all_path_are_empty) || storage_config.IsValid()) && limits_valid;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "engine/routing_algorithms/routing_base_ch.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
@@ -20,34 +19,18 @@ namespace
|
||||
{
|
||||
struct NodeBucket
|
||||
{
|
||||
NodeID middle_node;
|
||||
unsigned column_index; // a column in the weight/duration matrix
|
||||
unsigned target_id; // essentially a row in the weight matrix
|
||||
EdgeWeight weight;
|
||||
EdgeDuration duration;
|
||||
|
||||
NodeBucket(NodeID middle_node, unsigned column_index, EdgeWeight weight, EdgeDuration duration)
|
||||
: middle_node(middle_node), column_index(column_index), weight(weight), duration(duration)
|
||||
EdgeWeight duration;
|
||||
NodeBucket(const unsigned target_id, const EdgeWeight weight, const EdgeWeight duration)
|
||||
: target_id(target_id), weight(weight), duration(duration)
|
||||
{
|
||||
}
|
||||
|
||||
// partial order comparison
|
||||
bool operator<(const NodeBucket &rhs) const { return middle_node < rhs.middle_node; }
|
||||
|
||||
// functor for equal_range
|
||||
struct Compare
|
||||
{
|
||||
bool operator()(const NodeBucket &lhs, const NodeID &rhs) const
|
||||
{
|
||||
return lhs.middle_node < rhs;
|
||||
}
|
||||
|
||||
bool operator()(const NodeID &lhs, const NodeBucket &rhs) const
|
||||
{
|
||||
return lhs < rhs.middle_node;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// FIXME This should be replaced by an std::unordered_multimap, though this needs benchmarking
|
||||
using SearchSpaceWithBuckets = std::unordered_map<NodeID, std::vector<NodeBucket>>;
|
||||
|
||||
inline bool addLoopWeight(const DataFacade<ch::Algorithm> &facade,
|
||||
const NodeID node,
|
||||
EdgeWeight &weight,
|
||||
@@ -91,12 +74,12 @@ void relaxOutgoingEdges(const DataFacade<ch::Algorithm> &facade,
|
||||
{
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
|
||||
const auto edge_weight = data.weight;
|
||||
const auto edge_duration = data.duration;
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
const EdgeWeight edge_duration = data.duration;
|
||||
|
||||
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
|
||||
const auto to_weight = weight + edge_weight;
|
||||
const auto to_duration = duration + edge_duration;
|
||||
const EdgeWeight to_weight = weight + edge_weight;
|
||||
const EdgeWeight to_duration = duration + edge_duration;
|
||||
|
||||
// New Node discovered -> Add to Heap + Node Info Storage
|
||||
if (!query_heap.WasInserted(to))
|
||||
@@ -218,12 +201,12 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto edge_weight = data.weight;
|
||||
const auto edge_duration = data.duration;
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
const EdgeWeight edge_duration = data.duration;
|
||||
|
||||
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
|
||||
const auto to_weight = weight + edge_weight;
|
||||
const auto to_duration = duration + edge_duration;
|
||||
const EdgeWeight to_weight = weight + edge_weight;
|
||||
const EdgeWeight to_duration = duration + edge_duration;
|
||||
|
||||
// New Node discovered -> Add to Heap + Node Info Storage
|
||||
if (!query_heap.WasInserted(to))
|
||||
@@ -246,46 +229,48 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
|
||||
const unsigned row_idx,
|
||||
const unsigned number_of_targets,
|
||||
typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &query_heap,
|
||||
const std::vector<NodeBucket> &search_space_with_buckets,
|
||||
const SearchSpaceWithBuckets &search_space_with_buckets,
|
||||
std::vector<EdgeWeight> &weights_table,
|
||||
std::vector<EdgeDuration> &durations_table,
|
||||
std::vector<EdgeWeight> &durations_table,
|
||||
const PhantomNode &phantom_node)
|
||||
{
|
||||
const auto node = query_heap.DeleteMin();
|
||||
const auto source_weight = query_heap.GetKey(node);
|
||||
const auto source_duration = query_heap.GetData(node).duration;
|
||||
const NodeID node = query_heap.DeleteMin();
|
||||
const EdgeWeight source_weight = query_heap.GetKey(node);
|
||||
const EdgeWeight source_duration = query_heap.GetData(node).duration;
|
||||
|
||||
// check if each encountered node has an entry
|
||||
const auto &bucket_list = std::equal_range(search_space_with_buckets.begin(),
|
||||
search_space_with_buckets.end(),
|
||||
node,
|
||||
NodeBucket::Compare());
|
||||
for (const auto ¤t_bucket : boost::make_iterator_range(bucket_list))
|
||||
const auto bucket_iterator = search_space_with_buckets.find(node);
|
||||
// iterate bucket if there exists one
|
||||
if (bucket_iterator != search_space_with_buckets.end())
|
||||
{
|
||||
// get target id from bucket entry
|
||||
const auto column_idx = current_bucket.column_index;
|
||||
const auto target_weight = current_bucket.weight;
|
||||
const auto target_duration = current_bucket.duration;
|
||||
|
||||
auto ¤t_weight = weights_table[row_idx * number_of_targets + column_idx];
|
||||
auto ¤t_duration = durations_table[row_idx * number_of_targets + column_idx];
|
||||
|
||||
// check if new weight is better
|
||||
auto new_weight = source_weight + target_weight;
|
||||
auto new_duration = source_duration + target_duration;
|
||||
|
||||
if (new_weight < 0)
|
||||
const std::vector<NodeBucket> &bucket_list = bucket_iterator->second;
|
||||
for (const NodeBucket ¤t_bucket : bucket_list)
|
||||
{
|
||||
if (addLoopWeight(facade, node, new_weight, new_duration))
|
||||
// get target id from bucket entry
|
||||
const unsigned column_idx = current_bucket.target_id;
|
||||
const EdgeWeight target_weight = current_bucket.weight;
|
||||
const EdgeWeight target_duration = current_bucket.duration;
|
||||
|
||||
auto ¤t_weight = weights_table[row_idx * number_of_targets + column_idx];
|
||||
auto ¤t_duration = durations_table[row_idx * number_of_targets + column_idx];
|
||||
|
||||
// check if new weight is better
|
||||
auto new_weight = source_weight + target_weight;
|
||||
auto new_duration = source_duration + target_duration;
|
||||
|
||||
if (new_weight < 0)
|
||||
{
|
||||
current_weight = std::min(current_weight, new_weight);
|
||||
current_duration = std::min(current_duration, new_duration);
|
||||
if (addLoopWeight(facade, node, new_weight, new_duration))
|
||||
{
|
||||
current_weight = std::min(current_weight, new_weight);
|
||||
current_duration = std::min(current_duration, new_duration);
|
||||
}
|
||||
}
|
||||
else if (new_weight < current_weight)
|
||||
{
|
||||
current_weight = new_weight;
|
||||
current_duration = new_duration;
|
||||
}
|
||||
}
|
||||
else if (new_weight < current_weight)
|
||||
{
|
||||
current_weight = new_weight;
|
||||
current_duration = new_duration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,15 +282,15 @@ template <typename Algorithm>
|
||||
void backwardRoutingStep(const DataFacade<Algorithm> &facade,
|
||||
const unsigned column_idx,
|
||||
typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &query_heap,
|
||||
std::vector<NodeBucket> &search_space_with_buckets,
|
||||
SearchSpaceWithBuckets &search_space_with_buckets,
|
||||
const PhantomNode &phantom_node)
|
||||
{
|
||||
const auto node = query_heap.DeleteMin();
|
||||
const auto target_weight = query_heap.GetKey(node);
|
||||
const auto target_duration = query_heap.GetData(node).duration;
|
||||
const NodeID node = query_heap.DeleteMin();
|
||||
const EdgeWeight target_weight = query_heap.GetKey(node);
|
||||
const EdgeWeight target_duration = query_heap.GetData(node).duration;
|
||||
|
||||
// store settled nodes in search space bucket
|
||||
search_space_with_buckets.emplace_back(node, column_idx, target_weight, target_duration);
|
||||
search_space_with_buckets[node].emplace_back(column_idx, target_weight, target_duration);
|
||||
|
||||
relaxOutgoingEdges<REVERSE_DIRECTION>(
|
||||
facade, node, target_weight, target_duration, query_heap, phantom_node);
|
||||
@@ -316,92 +301,91 @@ template <typename Algorithm>
|
||||
std::vector<EdgeWeight> manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::vector<std::size_t> source_indices,
|
||||
std::vector<std::size_t> target_indices)
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices)
|
||||
{
|
||||
if (source_indices.empty())
|
||||
{
|
||||
source_indices.resize(phantom_nodes.size());
|
||||
std::iota(source_indices.begin(), source_indices.end(), 0);
|
||||
}
|
||||
if (target_indices.empty())
|
||||
{
|
||||
target_indices.resize(phantom_nodes.size());
|
||||
std::iota(target_indices.begin(), target_indices.end(), 0);
|
||||
}
|
||||
|
||||
const auto number_of_sources = source_indices.size();
|
||||
const auto number_of_targets = target_indices.size();
|
||||
const auto number_of_sources =
|
||||
source_indices.empty() ? phantom_nodes.size() : source_indices.size();
|
||||
const auto number_of_targets =
|
||||
target_indices.empty() ? phantom_nodes.size() : target_indices.size();
|
||||
const auto number_of_entries = number_of_sources * number_of_targets;
|
||||
|
||||
std::vector<EdgeWeight> weights_table(number_of_entries, INVALID_EDGE_WEIGHT);
|
||||
std::vector<EdgeDuration> durations_table(number_of_entries, MAXIMAL_EDGE_DURATION);
|
||||
std::vector<EdgeWeight> durations_table(number_of_entries, MAXIMAL_EDGE_DURATION);
|
||||
|
||||
std::mutex lock;
|
||||
std::vector<NodeBucket> search_space_with_buckets;
|
||||
engine_working_data.InitializeOrClearManyToManyThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
// Backward search for target phantoms
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<std::size_t>{0, target_indices.size()},
|
||||
[&](const tbb::blocked_range<std::size_t> &chunk) {
|
||||
for (auto column_idx = chunk.begin(), end = chunk.end(); column_idx != end;
|
||||
++column_idx)
|
||||
{
|
||||
const auto index = target_indices[column_idx];
|
||||
const auto &phantom = phantom_nodes[index];
|
||||
auto &query_heap = *(engine_working_data.many_to_many_heap);
|
||||
|
||||
engine_working_data.InitializeOrClearManyToManyThreadLocalStorage(
|
||||
facade.GetNumberOfNodes());
|
||||
auto &query_heap = *(engine_working_data.many_to_many_heap);
|
||||
insertTargetInHeap(query_heap, phantom);
|
||||
SearchSpaceWithBuckets search_space_with_buckets;
|
||||
|
||||
// explore search space
|
||||
std::vector<NodeBucket> local_buckets;
|
||||
while (!query_heap.Empty())
|
||||
{
|
||||
backwardRoutingStep(facade, column_idx, query_heap, local_buckets, phantom);
|
||||
}
|
||||
unsigned column_idx = 0;
|
||||
const auto search_target_phantom = [&](const PhantomNode &phantom) {
|
||||
// clear heap and insert target nodes
|
||||
query_heap.Clear();
|
||||
insertTargetInHeap(query_heap, phantom);
|
||||
|
||||
{ // Insert local buckets into the global search space
|
||||
std::lock_guard<std::mutex> guard{lock};
|
||||
search_space_with_buckets.insert(std::end(search_space_with_buckets),
|
||||
std::begin(local_buckets),
|
||||
std::end(local_buckets));
|
||||
}
|
||||
}
|
||||
});
|
||||
// explore search space
|
||||
while (!query_heap.Empty())
|
||||
{
|
||||
backwardRoutingStep(facade, column_idx, query_heap, search_space_with_buckets, phantom);
|
||||
}
|
||||
++column_idx;
|
||||
};
|
||||
|
||||
tbb::parallel_sort(search_space_with_buckets.begin(), search_space_with_buckets.end());
|
||||
// for each source do forward search
|
||||
unsigned row_idx = 0;
|
||||
const auto search_source_phantom = [&](const PhantomNode &phantom) {
|
||||
// clear heap and insert source nodes
|
||||
query_heap.Clear();
|
||||
insertSourceInHeap(query_heap, phantom);
|
||||
|
||||
// For each source do forward search
|
||||
tbb::parallel_for(tbb::blocked_range<std::size_t>{0, source_indices.size()},
|
||||
[&](const tbb::blocked_range<std::size_t> &chunk) {
|
||||
for (auto row_idx = chunk.begin(), end = chunk.end(); row_idx != end;
|
||||
++row_idx)
|
||||
{
|
||||
const auto index = source_indices[row_idx];
|
||||
const auto &phantom = phantom_nodes[index];
|
||||
// explore search space
|
||||
while (!query_heap.Empty())
|
||||
{
|
||||
forwardRoutingStep(facade,
|
||||
row_idx,
|
||||
number_of_targets,
|
||||
query_heap,
|
||||
search_space_with_buckets,
|
||||
weights_table,
|
||||
durations_table,
|
||||
phantom);
|
||||
}
|
||||
++row_idx;
|
||||
};
|
||||
|
||||
// clear heap and insert source nodes
|
||||
engine_working_data.InitializeOrClearManyToManyThreadLocalStorage(
|
||||
facade.GetNumberOfNodes());
|
||||
auto &query_heap = *(engine_working_data.many_to_many_heap);
|
||||
insertSourceInHeap(query_heap, phantom);
|
||||
if (target_indices.empty())
|
||||
{
|
||||
for (const auto &phantom : phantom_nodes)
|
||||
{
|
||||
search_target_phantom(phantom);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto index : target_indices)
|
||||
{
|
||||
const auto &phantom = phantom_nodes[index];
|
||||
search_target_phantom(phantom);
|
||||
}
|
||||
}
|
||||
|
||||
// explore search space
|
||||
while (!query_heap.Empty())
|
||||
{
|
||||
forwardRoutingStep(facade,
|
||||
row_idx,
|
||||
number_of_targets,
|
||||
query_heap,
|
||||
search_space_with_buckets,
|
||||
weights_table,
|
||||
durations_table,
|
||||
phantom);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (source_indices.empty())
|
||||
{
|
||||
for (const auto &phantom : phantom_nodes)
|
||||
{
|
||||
search_source_phantom(phantom);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto index : source_indices)
|
||||
{
|
||||
const auto &phantom = phantom_nodes[index];
|
||||
search_source_phantom(phantom);
|
||||
}
|
||||
}
|
||||
|
||||
return durations_table;
|
||||
}
|
||||
@@ -410,15 +394,15 @@ template std::vector<EdgeWeight>
|
||||
manyToManySearch(SearchEngineData<ch::Algorithm> &engine_working_data,
|
||||
const DataFacade<ch::Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::vector<std::size_t> source_indices,
|
||||
std::vector<std::size_t> target_indices);
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices);
|
||||
|
||||
template std::vector<EdgeWeight>
|
||||
manyToManySearch(SearchEngineData<mld::Algorithm> &engine_working_data,
|
||||
const DataFacade<mld::Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::vector<std::size_t> source_indices,
|
||||
std::vector<std::size_t> target_indices);
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices);
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/extraction_containers.hpp"
|
||||
#include "extractor/extraction_node.hpp"
|
||||
#include "extractor/extraction_relation.hpp"
|
||||
#include "extractor/extraction_way.hpp"
|
||||
#include "extractor/extractor_callbacks.hpp"
|
||||
#include "extractor/files.hpp"
|
||||
@@ -289,13 +288,12 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
|
||||
const osmium::io::File input_file(config.input_path.string());
|
||||
osmium::thread::Pool pool(number_of_threads);
|
||||
|
||||
std::unique_ptr<osmium::io::Reader> reader(new osmium::io::Reader(
|
||||
osmium::io::Reader reader(
|
||||
input_file,
|
||||
osmium::osm_entity_bits::relation,
|
||||
(config.use_metadata ? osmium::io::read_meta::yes : osmium::io::read_meta::no)));
|
||||
pool,
|
||||
(config.use_metadata ? osmium::io::read_meta::yes : osmium::io::read_meta::no));
|
||||
|
||||
osmium::io::Header header = reader->header();
|
||||
const osmium::io::Header header = reader.header();
|
||||
|
||||
unsigned number_of_nodes = 0;
|
||||
unsigned number_of_ways = 0;
|
||||
@@ -333,7 +331,6 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
|
||||
timestamp_file.WriteFrom(timestamp.c_str(), timestamp.length());
|
||||
|
||||
ExtractionRelationContainer relations;
|
||||
std::vector<std::string> restrictions = scripting_environment.GetRestrictions();
|
||||
// setup restriction parser
|
||||
const RestrictionParser restriction_parser(
|
||||
@@ -341,19 +338,20 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
config.parse_conditionals,
|
||||
restrictions);
|
||||
|
||||
std::mutex process_mutex;
|
||||
|
||||
using SharedBuffer = std::shared_ptr<const osmium::memory::Buffer>;
|
||||
struct ParsedBuffer
|
||||
{
|
||||
SharedBuffer buffer;
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> resulting_nodes;
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> resulting_ways;
|
||||
std::vector<std::pair<const osmium::Relation &, ExtractionRelation>> resulting_relations;
|
||||
std::vector<InputConditionalTurnRestriction> resulting_restrictions;
|
||||
};
|
||||
|
||||
tbb::filter_t<void, SharedBuffer> buffer_reader(
|
||||
tbb::filter::serial_in_order, [&](tbb::flow_control &fc) {
|
||||
if (auto buffer = reader->read())
|
||||
if (auto buffer = reader.read())
|
||||
{
|
||||
return std::make_shared<const osmium::memory::Buffer>(std::move(buffer));
|
||||
}
|
||||
@@ -372,10 +370,8 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
parsed_buffer->buffer = buffer;
|
||||
scripting_environment.ProcessElements(*buffer,
|
||||
restriction_parser,
|
||||
relations,
|
||||
parsed_buffer->resulting_nodes,
|
||||
parsed_buffer->resulting_ways,
|
||||
parsed_buffer->resulting_relations,
|
||||
parsed_buffer->resulting_restrictions);
|
||||
return parsed_buffer;
|
||||
});
|
||||
@@ -395,46 +391,13 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
{
|
||||
extractor_callbacks->ProcessWay(result.first, result.second);
|
||||
}
|
||||
});
|
||||
|
||||
tbb::filter_t<std::shared_ptr<ParsedBuffer>, void> buffer_storage_relation(
|
||||
tbb::filter::serial_in_order, [&](const std::shared_ptr<ParsedBuffer> parsed_buffer) {
|
||||
if (!parsed_buffer)
|
||||
return;
|
||||
|
||||
number_of_relations += parsed_buffer->resulting_relations.size();
|
||||
for (const auto &result : parsed_buffer->resulting_relations)
|
||||
{
|
||||
/// TODO: add restriction processing
|
||||
if (result.second.is_restriction)
|
||||
continue;
|
||||
|
||||
relations.AddRelation(result.second);
|
||||
}
|
||||
|
||||
number_of_relations += parsed_buffer->resulting_restrictions.size();
|
||||
for (const auto &result : parsed_buffer->resulting_restrictions)
|
||||
{
|
||||
extractor_callbacks->ProcessRestriction(result);
|
||||
}
|
||||
});
|
||||
|
||||
/* Main trick that we can use the same pipeline. It just receive relation objects
|
||||
* from osmium. So other containers would be empty and doesn't process anything
|
||||
*/
|
||||
util::Log() << "Parse relations ...";
|
||||
tbb::parallel_pipeline(tbb::task_scheduler_init::default_num_threads() * 1.5,
|
||||
buffer_reader & buffer_transform & buffer_storage_relation);
|
||||
reader->close();
|
||||
|
||||
/* At this step we just filter ways and nodes from osmium, so any relation wouldn't be
|
||||
* processed there.
|
||||
*/
|
||||
util::Log() << "Parse ways and nodes ...";
|
||||
reader.reset(new osmium::io::Reader(
|
||||
input_file,
|
||||
osmium::osm_entity_bits::node | osmium::osm_entity_bits::way,
|
||||
(config.use_metadata ? osmium::io::read_meta::yes : osmium::io::read_meta::no)));
|
||||
|
||||
// Number of pipeline tokens that yielded the best speedup was about 1.5 * num_cores
|
||||
tbb::parallel_pipeline(tbb::task_scheduler_init::default_num_threads() * 1.5,
|
||||
buffer_reader & buffer_transform & buffer_storage);
|
||||
|
||||
@@ -54,18 +54,11 @@ IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_i
|
||||
const boost::optional<NodeID> sorting_base,
|
||||
const bool use_low_precision_angles) const
|
||||
{
|
||||
const auto intersection_degree = node_based_graph.GetOutDegree(node_at_center_of_intersection);
|
||||
const util::Coordinate turn_coordinate = coordinates[node_at_center_of_intersection];
|
||||
|
||||
// compute bearings in a relatively small circle to prevent wrong roads order with true bearings
|
||||
struct RoadWithInitialBearing
|
||||
{
|
||||
double bearing;
|
||||
IntersectionShapeData road;
|
||||
};
|
||||
std::vector<RoadWithInitialBearing> initial_roads_ordering;
|
||||
IntersectionShape intersection;
|
||||
// reserve enough items (+ the possibly missing u-turn edge)
|
||||
initial_roads_ordering.reserve(intersection_degree);
|
||||
const auto intersection_degree = node_based_graph.GetOutDegree(node_at_center_of_intersection);
|
||||
intersection.reserve(intersection_degree);
|
||||
const util::Coordinate turn_coordinate = coordinates[node_at_center_of_intersection];
|
||||
|
||||
// number of lanes at the intersection changes how far we look down the road
|
||||
const auto edge_range = node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection);
|
||||
@@ -89,11 +82,6 @@ IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_i
|
||||
auto coordinates = coordinate_extractor.GetCoordinatesAlongRoad(
|
||||
node_at_center_of_intersection, edge_connected_to_intersection, !INVERT, to_node);
|
||||
|
||||
const auto close_coordinate =
|
||||
coordinate_extractor.ExtractCoordinateAtLength(2. /*m*/, coordinates);
|
||||
const auto initial_bearing =
|
||||
util::coordinate_calculation::bearing(turn_coordinate, close_coordinate);
|
||||
|
||||
const auto segment_length = util::coordinate_calculation::getLength(
|
||||
coordinates.begin(),
|
||||
coordinates.end(),
|
||||
@@ -135,79 +123,31 @@ IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_i
|
||||
BOOST_ASSERT(std::abs(bearing) <= 0.1);
|
||||
}
|
||||
|
||||
initial_roads_ordering.push_back(
|
||||
{initial_bearing, {edge_connected_to_intersection, bearing, segment_length}});
|
||||
intersection.push_back({edge_connected_to_intersection, bearing, segment_length});
|
||||
}
|
||||
|
||||
if (!initial_roads_ordering.empty())
|
||||
if (!intersection.empty())
|
||||
{
|
||||
const auto base_initial_bearing = [&]() {
|
||||
const auto base_bearing = [&]() {
|
||||
if (sorting_base)
|
||||
{
|
||||
const auto itr = std::find_if(initial_roads_ordering.begin(),
|
||||
initial_roads_ordering.end(),
|
||||
[&](const auto &data) {
|
||||
return node_based_graph.GetTarget(
|
||||
data.road.eid) == *sorting_base;
|
||||
});
|
||||
if (itr != initial_roads_ordering.end())
|
||||
const auto itr =
|
||||
std::find_if(intersection.begin(),
|
||||
intersection.end(),
|
||||
[&](const IntersectionShapeData &data) {
|
||||
return node_based_graph.GetTarget(data.eid) == *sorting_base;
|
||||
});
|
||||
if (itr != intersection.end())
|
||||
return util::bearing::reverse(itr->bearing);
|
||||
}
|
||||
return util::bearing::reverse(initial_roads_ordering.begin()->bearing);
|
||||
return util::bearing::reverse(intersection.begin()->bearing);
|
||||
}();
|
||||
|
||||
// sort roads with respect to the initial bearings, a tie-breaker for equal initial bearings
|
||||
// is to order roads via final bearings to have roads in clockwise order
|
||||
//
|
||||
// rhs <---. lhs <----.
|
||||
// / /
|
||||
// lhs / rhs /
|
||||
//
|
||||
// lhs road is before rhs one rhs road is before lhs one
|
||||
// bearing::angleBetween < 180 bearing::angleBetween > 180
|
||||
const auto initial_bearing_order = makeCompareShapeDataAngleToBearing(base_initial_bearing);
|
||||
std::sort(initial_roads_ordering.begin(),
|
||||
initial_roads_ordering.end(),
|
||||
[&initial_bearing_order](const auto &lhs, const auto &rhs) {
|
||||
return initial_bearing_order(lhs, rhs) ||
|
||||
(lhs.bearing == rhs.bearing &&
|
||||
util::bearing::angleBetween(lhs.road.bearing, rhs.road.bearing) <
|
||||
180);
|
||||
});
|
||||
|
||||
// copy intersection data in the initial order
|
||||
IntersectionShape intersection;
|
||||
intersection.reserve(initial_roads_ordering.size());
|
||||
std::transform(initial_roads_ordering.begin(),
|
||||
initial_roads_ordering.end(),
|
||||
std::back_inserter(intersection),
|
||||
[](const auto &entry) { return entry.road; });
|
||||
|
||||
if (intersection.size() > 2)
|
||||
{ // Check bearings ordering with respect to true bearings
|
||||
const auto base_bearing = intersection.front().bearing;
|
||||
const auto bearings_order =
|
||||
makeCompareShapeDataAngleToBearing(util::bearing::reverse(base_bearing));
|
||||
for (auto curr = intersection.begin(), next = std::next(curr);
|
||||
next != intersection.end();
|
||||
++curr, ++next)
|
||||
{
|
||||
if (bearings_order(*next, *curr))
|
||||
{ // If the true bearing is out of the initial order (next before current) then
|
||||
// adjust the next bearing to keep the order. The adjustment angle is at most
|
||||
// 0.5° or a half-angle between the current bearing and the base bearing.
|
||||
// to prevent overlapping over base bearing + 360°.
|
||||
const auto angle_adjustment = std::min(
|
||||
.5, util::restrictAngleToValidRange(base_bearing - curr->bearing) / 2.);
|
||||
next->bearing =
|
||||
util::restrictAngleToValidRange(curr->bearing + angle_adjustment);
|
||||
}
|
||||
}
|
||||
}
|
||||
return intersection;
|
||||
std::sort(intersection.begin(),
|
||||
intersection.end(),
|
||||
makeCompareShapeDataAngleToBearing(base_bearing));
|
||||
}
|
||||
|
||||
return IntersectionShape{};
|
||||
return intersection;
|
||||
}
|
||||
|
||||
// a
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "extractor/extraction_helper_functions.hpp"
|
||||
#include "extractor/extraction_node.hpp"
|
||||
#include "extractor/extraction_relation.hpp"
|
||||
#include "extractor/extraction_segment.hpp"
|
||||
#include "extractor/extraction_turn.hpp"
|
||||
#include "extractor/extraction_way.hpp"
|
||||
@@ -32,9 +31,6 @@ template <> struct is_container<osmium::Node> : std::false_type
|
||||
template <> struct is_container<osmium::Way> : std::false_type
|
||||
{
|
||||
};
|
||||
template <> struct is_container<osmium::Relation> : std::false_type
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
namespace osrm
|
||||
@@ -220,14 +216,6 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"sharp_left",
|
||||
extractor::guidance::DirectionModifier::SharpLeft);
|
||||
|
||||
context.state.new_enum("item_type",
|
||||
"node",
|
||||
osmium::item_type::node,
|
||||
"way",
|
||||
osmium::item_type::way,
|
||||
"relation",
|
||||
osmium::item_type::relation);
|
||||
|
||||
context.state.new_usertype<RasterContainer>("raster",
|
||||
"load",
|
||||
&RasterContainer::LoadRasterSource,
|
||||
@@ -288,30 +276,6 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"version",
|
||||
&osmium::Way::version);
|
||||
|
||||
context.state.new_usertype<osmium::RelationMember>(
|
||||
"RelationMember",
|
||||
"role",
|
||||
&osmium::RelationMember::role,
|
||||
"type",
|
||||
&osmium::RelationMember::type,
|
||||
"id",
|
||||
[](const osmium::RelationMember &member) -> osmium::object_id_type {
|
||||
return member.ref();
|
||||
});
|
||||
|
||||
context.state.new_usertype<osmium::Relation>(
|
||||
"Relation",
|
||||
"get_value_by_key",
|
||||
&get_value_by_key<osmium::Relation>,
|
||||
"id",
|
||||
&osmium::Relation::id,
|
||||
"version",
|
||||
&osmium::Relation::version,
|
||||
"members",
|
||||
[](const osmium::Relation &rel) -> const osmium::RelationMemberList & {
|
||||
return rel.members();
|
||||
});
|
||||
|
||||
context.state.new_usertype<osmium::Node>("Node",
|
||||
"location",
|
||||
&osmium::Node::location,
|
||||
@@ -320,7 +284,7 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"id",
|
||||
&osmium::Node::id,
|
||||
"version",
|
||||
&osmium::Node::version);
|
||||
&osmium::Way::version);
|
||||
|
||||
context.state.new_usertype<ExtractionNode>("ResultNode",
|
||||
"traffic_lights",
|
||||
@@ -402,18 +366,6 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
sol::property([](const ExtractionWay &way) { return way.backward_restricted; },
|
||||
[](ExtractionWay &way, bool flag) { way.backward_restricted = flag; }));
|
||||
|
||||
context.state.new_usertype<ExtractionRelation>(
|
||||
"ExtractionRelation",
|
||||
sol::meta_function::new_index,
|
||||
[](ExtractionRelation &rel, const osmium::RelationMember &member)
|
||||
-> ExtractionRelation::AttributesMap & { return rel.GetMember(member); },
|
||||
sol::meta_function::index,
|
||||
[](ExtractionRelation &rel, const osmium::RelationMember &member)
|
||||
-> ExtractionRelation::AttributesMap & { return rel.GetMember(member); },
|
||||
"restriction",
|
||||
sol::property([](const ExtractionRelation &rel) { return rel.is_restriction; },
|
||||
[](ExtractionRelation &rel, bool flag) { rel.is_restriction = flag; }));
|
||||
|
||||
context.state.new_usertype<ExtractionSegment>("ExtractionSegment",
|
||||
"source",
|
||||
&ExtractionSegment::source,
|
||||
@@ -505,7 +457,10 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
util::Log() << "Using profile api version " << context.api_version;
|
||||
|
||||
// version-dependent parts of the api
|
||||
auto initV2Context = [&]() {
|
||||
switch (context.api_version)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
// clear global not used in v2
|
||||
context.state["properties"] = sol::nullopt;
|
||||
|
||||
@@ -588,22 +543,6 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
if (force_split_edges != sol::nullopt)
|
||||
context.properties.force_split_edges = force_split_edges.value();
|
||||
}
|
||||
};
|
||||
|
||||
switch (context.api_version)
|
||||
{
|
||||
case 3:
|
||||
{
|
||||
initV2Context();
|
||||
context.relation_function = function_table.value()["process_relation"];
|
||||
|
||||
context.has_relation_function = context.relation_function.valid();
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
initV2Context();
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
@@ -676,15 +615,12 @@ LuaScriptingContext &Sol2ScriptingEnvironment::GetSol2Context()
|
||||
void Sol2ScriptingEnvironment::ProcessElements(
|
||||
const osmium::memory::Buffer &buffer,
|
||||
const RestrictionParser &restriction_parser,
|
||||
const ExtractionRelationContainer &relations,
|
||||
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
||||
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
||||
std::vector<std::pair<const osmium::Relation &, ExtractionRelation>> &resulting_relations,
|
||||
std::vector<InputConditionalTurnRestriction> &resulting_restrictions)
|
||||
{
|
||||
ExtractionNode result_node;
|
||||
ExtractionWay result_way;
|
||||
ExtractionRelation result_relation;
|
||||
auto &local_context = this->GetSol2Context();
|
||||
|
||||
for (auto entity = buffer.cbegin(), end = buffer.cend(); entity != end; ++entity)
|
||||
@@ -692,47 +628,33 @@ void Sol2ScriptingEnvironment::ProcessElements(
|
||||
switch (entity->type())
|
||||
{
|
||||
case osmium::item_type::node:
|
||||
{
|
||||
const auto &node = static_cast<const osmium::Node &>(*entity);
|
||||
result_node.clear();
|
||||
if (local_context.has_node_function &&
|
||||
(!node.tags().empty() || local_context.properties.call_tagless_node_function))
|
||||
(!static_cast<const osmium::Node &>(*entity).tags().empty() ||
|
||||
local_context.properties.call_tagless_node_function))
|
||||
{
|
||||
const auto &id = ExtractionRelation::OsmIDTyped(node.id(), osmium::item_type::node);
|
||||
local_context.ProcessNode(node, result_node, relations.Get(id));
|
||||
local_context.ProcessNode(static_cast<const osmium::Node &>(*entity), result_node);
|
||||
}
|
||||
resulting_nodes.push_back({node, std::move(result_node)});
|
||||
}
|
||||
break;
|
||||
resulting_nodes.push_back(std::pair<const osmium::Node &, ExtractionNode>(
|
||||
static_cast<const osmium::Node &>(*entity), std::move(result_node)));
|
||||
break;
|
||||
case osmium::item_type::way:
|
||||
{
|
||||
const osmium::Way &way = static_cast<const osmium::Way &>(*entity);
|
||||
result_way.clear();
|
||||
if (local_context.has_way_function)
|
||||
{
|
||||
const auto &id = ExtractionRelation::OsmIDTyped(way.id(), osmium::item_type::way);
|
||||
local_context.ProcessWay(way, result_way, relations.Get(id));
|
||||
local_context.ProcessWay(static_cast<const osmium::Way &>(*entity), result_way);
|
||||
}
|
||||
resulting_ways.push_back({way, std::move(result_way)});
|
||||
}
|
||||
break;
|
||||
resulting_ways.push_back(std::pair<const osmium::Way &, ExtractionWay>(
|
||||
static_cast<const osmium::Way &>(*entity), std::move(result_way)));
|
||||
break;
|
||||
case osmium::item_type::relation:
|
||||
{
|
||||
const auto &relation = static_cast<const osmium::Relation &>(*entity);
|
||||
if (auto result_res = restriction_parser.TryParse(relation))
|
||||
auto result_res =
|
||||
restriction_parser.TryParse(static_cast<const osmium::Relation &>(*entity));
|
||||
if (result_res)
|
||||
{
|
||||
resulting_restrictions.push_back(*result_res);
|
||||
}
|
||||
|
||||
if (local_context.api_version > 2)
|
||||
{
|
||||
result_relation.clear();
|
||||
if (local_context.has_relation_function)
|
||||
{
|
||||
local_context.ProcessRelation(relation, result_relation);
|
||||
}
|
||||
resulting_relations.push_back({relation, std::move(result_relation)});
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -810,7 +732,6 @@ std::vector<std::vector<std::string>> Sol2ScriptingEnvironment::GetExcludableCla
|
||||
auto &context = GetSol2Context();
|
||||
switch (context.api_version)
|
||||
{
|
||||
case 3:
|
||||
case 2:
|
||||
return Sol2ScriptingEnvironment::GetStringListsFromTable("excludable");
|
||||
default:
|
||||
@@ -823,7 +744,6 @@ std::vector<std::string> Sol2ScriptingEnvironment::GetClassNames()
|
||||
auto &context = GetSol2Context();
|
||||
switch (context.api_version)
|
||||
{
|
||||
case 3:
|
||||
case 2:
|
||||
return Sol2ScriptingEnvironment::GetStringListFromTable("classes");
|
||||
default:
|
||||
@@ -836,7 +756,6 @@ std::vector<std::string> Sol2ScriptingEnvironment::GetNameSuffixList()
|
||||
auto &context = GetSol2Context();
|
||||
switch (context.api_version)
|
||||
{
|
||||
case 3:
|
||||
case 2:
|
||||
return Sol2ScriptingEnvironment::GetStringListFromTable("suffix_list");
|
||||
case 1:
|
||||
@@ -851,7 +770,6 @@ std::vector<std::string> Sol2ScriptingEnvironment::GetRestrictions()
|
||||
auto &context = GetSol2Context();
|
||||
switch (context.api_version)
|
||||
{
|
||||
case 3:
|
||||
case 2:
|
||||
return Sol2ScriptingEnvironment::GetStringListFromTable("restrictions");
|
||||
case 1:
|
||||
@@ -867,7 +785,6 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn)
|
||||
|
||||
switch (context.api_version)
|
||||
{
|
||||
case 3:
|
||||
case 2:
|
||||
if (context.has_turn_penalty_function)
|
||||
{
|
||||
@@ -934,7 +851,6 @@ void Sol2ScriptingEnvironment::ProcessSegment(ExtractionSegment &segment)
|
||||
{
|
||||
switch (context.api_version)
|
||||
{
|
||||
case 3:
|
||||
case 2:
|
||||
context.segment_function(context.profile_table, segment);
|
||||
break;
|
||||
@@ -950,17 +866,12 @@ void Sol2ScriptingEnvironment::ProcessSegment(ExtractionSegment &segment)
|
||||
}
|
||||
}
|
||||
|
||||
void LuaScriptingContext::ProcessNode(const osmium::Node &node,
|
||||
ExtractionNode &result,
|
||||
const ExtractionRelationContainer::RelationList &relations)
|
||||
void LuaScriptingContext::ProcessNode(const osmium::Node &node, ExtractionNode &result)
|
||||
{
|
||||
BOOST_ASSERT(state.lua_state() != nullptr);
|
||||
|
||||
switch (api_version)
|
||||
{
|
||||
case 3:
|
||||
node_function(profile_table, node, result, relations);
|
||||
break;
|
||||
case 2:
|
||||
node_function(profile_table, node, result);
|
||||
break;
|
||||
@@ -971,17 +882,12 @@ void LuaScriptingContext::ProcessNode(const osmium::Node &node,
|
||||
}
|
||||
}
|
||||
|
||||
void LuaScriptingContext::ProcessWay(const osmium::Way &way,
|
||||
ExtractionWay &result,
|
||||
const ExtractionRelationContainer::RelationList &relations)
|
||||
void LuaScriptingContext::ProcessWay(const osmium::Way &way, ExtractionWay &result)
|
||||
{
|
||||
BOOST_ASSERT(state.lua_state() != nullptr);
|
||||
|
||||
switch (api_version)
|
||||
{
|
||||
case 3:
|
||||
way_function(profile_table, way, result, relations);
|
||||
break;
|
||||
case 2:
|
||||
way_function(profile_table, way, result);
|
||||
break;
|
||||
@@ -991,15 +897,5 @@ void LuaScriptingContext::ProcessWay(const osmium::Way &way,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LuaScriptingContext::ProcessRelation(const osmium::Relation &relation,
|
||||
ExtractionRelation &result)
|
||||
{
|
||||
BOOST_ASSERT(state.lua_state() != nullptr);
|
||||
BOOST_ASSERT(api_version > 2);
|
||||
|
||||
relation_function(profile_table, relation, result);
|
||||
}
|
||||
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
}
|
||||
|
||||
+53
-48
@@ -52,49 +52,46 @@ const static unsigned INIT_OK_START_ENGINE = 0;
|
||||
const static unsigned INIT_OK_DO_NOT_START_ENGINE = 1;
|
||||
const static unsigned INIT_FAILED = -1;
|
||||
|
||||
namespace osrm
|
||||
static EngineConfig::Algorithm stringToAlgorithm(std::string algorithm)
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
std::istream &operator>>(std::istream &in, EngineConfig::Algorithm &algorithm)
|
||||
{
|
||||
std::string token;
|
||||
in >> token;
|
||||
boost::to_lower(token);
|
||||
boost::to_lower(algorithm);
|
||||
|
||||
if (token == "ch")
|
||||
algorithm = EngineConfig::Algorithm::CH;
|
||||
else if (token == "corech")
|
||||
algorithm = EngineConfig::Algorithm::CoreCH;
|
||||
else if (token == "mld")
|
||||
algorithm = EngineConfig::Algorithm::MLD;
|
||||
else
|
||||
throw util::RuntimeError(token, ErrorCode::UnknownAlgorithm, SOURCE_REF);
|
||||
return in;
|
||||
}
|
||||
}
|
||||
if (algorithm == "ch")
|
||||
return EngineConfig::Algorithm::CH;
|
||||
if (algorithm == "corech")
|
||||
return EngineConfig::Algorithm::CoreCH;
|
||||
if (algorithm == "mld")
|
||||
return EngineConfig::Algorithm::MLD;
|
||||
throw util::RuntimeError(algorithm, ErrorCode::UnknownAlgorithm, SOURCE_REF);
|
||||
}
|
||||
|
||||
// generate boost::program_options object for the routing part
|
||||
inline unsigned generateServerProgramOptions(const int argc,
|
||||
const char *argv[],
|
||||
std::string verbosity,
|
||||
boost::filesystem::path &base_path,
|
||||
std::string &ip_address,
|
||||
int &ip_port,
|
||||
int &requested_num_threads,
|
||||
bool &use_shared_memory,
|
||||
std::string &algorithm,
|
||||
bool &trial,
|
||||
EngineConfig &config)
|
||||
int &max_locations_trip,
|
||||
int &max_locations_viaroute,
|
||||
int &max_locations_distance_table,
|
||||
int &max_locations_map_matching,
|
||||
int &max_results_nearest,
|
||||
int &max_alternatives)
|
||||
{
|
||||
using boost::program_options::value;
|
||||
using boost::filesystem::path;
|
||||
|
||||
const auto hardware_threads = std::max<int>(1, std::thread::hardware_concurrency());
|
||||
|
||||
// declare a group of options that will be allowed only on command line
|
||||
boost::program_options::options_description generic_options("Options");
|
||||
generic_options.add_options() //
|
||||
("version,v", "Show version")("help,h", "Show this help message")(
|
||||
"verbosity,l",
|
||||
boost::program_options::value<std::string>(&config.verbosity)->default_value("INFO"),
|
||||
boost::program_options::value<std::string>(&verbosity)->default_value("INFO"),
|
||||
std::string("Log verbosity level: " + util::LogPolicy::GetLevels()).c_str())(
|
||||
"trial", value<bool>(&trial)->implicit_value(true), "Quit after initialization");
|
||||
|
||||
@@ -108,32 +105,31 @@ inline unsigned generateServerProgramOptions(const int argc,
|
||||
value<int>(&ip_port)->default_value(5000),
|
||||
"TCP/IP port") //
|
||||
("threads,t",
|
||||
value<int>(&config.use_threads_number)->default_value(hardware_threads),
|
||||
value<int>(&requested_num_threads)->default_value(8),
|
||||
"Number of threads to use") //
|
||||
("shared-memory,s",
|
||||
value<bool>(&config.use_shared_memory)->implicit_value(true)->default_value(false),
|
||||
value<bool>(&use_shared_memory)->implicit_value(true)->default_value(false),
|
||||
"Load data from shared memory") //
|
||||
("algorithm,a",
|
||||
value<EngineConfig::Algorithm>(&config.algorithm)
|
||||
->default_value(EngineConfig::Algorithm::CH, "CH"),
|
||||
value<std::string>(&algorithm)->default_value("CH"),
|
||||
"Algorithm to use for the data. Can be CH, CoreCH, MLD.") //
|
||||
("max-viaroute-size",
|
||||
value<int>(&config.max_locations_viaroute)->default_value(500),
|
||||
value<int>(&max_locations_viaroute)->default_value(500),
|
||||
"Max. locations supported in viaroute query") //
|
||||
("max-trip-size",
|
||||
value<int>(&config.max_locations_trip)->default_value(100),
|
||||
value<int>(&max_locations_trip)->default_value(100),
|
||||
"Max. locations supported in trip query") //
|
||||
("max-table-size",
|
||||
value<int>(&config.max_locations_distance_table)->default_value(100),
|
||||
value<int>(&max_locations_distance_table)->default_value(100),
|
||||
"Max. locations supported in distance table query") //
|
||||
("max-matching-size",
|
||||
value<int>(&config.max_locations_map_matching)->default_value(100),
|
||||
value<int>(&max_locations_map_matching)->default_value(100),
|
||||
"Max. locations supported in map matching query") //
|
||||
("max-nearest-size",
|
||||
value<int>(&config.max_results_nearest)->default_value(100),
|
||||
value<int>(&max_results_nearest)->default_value(100),
|
||||
"Max. results supported in nearest query") //
|
||||
("max-alternatives",
|
||||
value<int>(&config.max_alternatives)->default_value(3),
|
||||
value<int>(&max_alternatives)->default_value(3),
|
||||
"Max. number of alternatives supported in the MLD route query");
|
||||
|
||||
// hidden options, will be allowed on command line, but will not be shown to the user
|
||||
@@ -184,22 +180,19 @@ inline unsigned generateServerProgramOptions(const int argc,
|
||||
|
||||
boost::program_options::notify(option_variables);
|
||||
|
||||
if (!config.use_shared_memory && option_variables.count("base"))
|
||||
if (!use_shared_memory && option_variables.count("base"))
|
||||
{
|
||||
return INIT_OK_START_ENGINE;
|
||||
}
|
||||
else if (config.use_shared_memory && !option_variables.count("base"))
|
||||
else if (use_shared_memory && !option_variables.count("base"))
|
||||
{
|
||||
return INIT_OK_START_ENGINE;
|
||||
}
|
||||
else if (config.use_shared_memory && option_variables.count("base"))
|
||||
else if (use_shared_memory && option_variables.count("base"))
|
||||
{
|
||||
util::Log(logWARNING) << "Shared memory settings conflict with path settings.";
|
||||
}
|
||||
|
||||
// Adjust number of threads to hardware concurrency
|
||||
config.use_threads_number = std::min(hardware_threads, config.use_threads_number);
|
||||
|
||||
std::cout << visible_options;
|
||||
return INIT_OK_DO_NOT_START_ENGINE;
|
||||
}
|
||||
@@ -210,13 +203,28 @@ int main(int argc, const char *argv[]) try
|
||||
|
||||
bool trial_run = false;
|
||||
std::string ip_address;
|
||||
int ip_port;
|
||||
int ip_port, requested_thread_num;
|
||||
|
||||
EngineConfig config;
|
||||
std::string verbosity;
|
||||
boost::filesystem::path base_path;
|
||||
|
||||
const unsigned init_result =
|
||||
generateServerProgramOptions(argc, argv, base_path, ip_address, ip_port, trial_run, config);
|
||||
std::string algorithm;
|
||||
const unsigned init_result = generateServerProgramOptions(argc,
|
||||
argv,
|
||||
verbosity,
|
||||
base_path,
|
||||
ip_address,
|
||||
ip_port,
|
||||
requested_thread_num,
|
||||
config.use_shared_memory,
|
||||
algorithm,
|
||||
trial_run,
|
||||
config.max_locations_trip,
|
||||
config.max_locations_viaroute,
|
||||
config.max_locations_distance_table,
|
||||
config.max_locations_map_matching,
|
||||
config.max_results_nearest,
|
||||
config.max_alternatives);
|
||||
if (init_result == INIT_OK_DO_NOT_START_ENGINE)
|
||||
{
|
||||
return EXIT_SUCCESS;
|
||||
@@ -226,7 +234,7 @@ int main(int argc, const char *argv[]) try
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
util::LogPolicy::GetInstance().SetLevel(config.verbosity);
|
||||
util::LogPolicy::GetInstance().SetLevel(verbosity);
|
||||
|
||||
if (!base_path.empty())
|
||||
{
|
||||
@@ -245,6 +253,7 @@ int main(int argc, const char *argv[]) try
|
||||
}
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
config.algorithm = stringToAlgorithm(algorithm);
|
||||
|
||||
util::Log() << "starting up engines, " << OSRM_VERSION;
|
||||
|
||||
@@ -253,10 +262,6 @@ int main(int argc, const char *argv[]) try
|
||||
util::Log() << "Loading from shared memory";
|
||||
}
|
||||
|
||||
// Use the same number of threads for Server and TBB threads pools
|
||||
// It doubles number of used threads
|
||||
auto requested_thread_num = config.use_threads_number;
|
||||
|
||||
util::Log() << "Threads: " << requested_thread_num;
|
||||
util::Log() << "IP address: " << ip_address;
|
||||
util::Log() << "IP port: " << ip_port;
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ void LogPolicy::SetLevel(std::string const &level)
|
||||
else if (boost::iequals(level, "DEBUG"))
|
||||
m_level = logDEBUG;
|
||||
else
|
||||
m_level = logINFO;
|
||||
;
|
||||
}
|
||||
|
||||
LogPolicy &LogPolicy::GetInstance()
|
||||
|
||||
@@ -153,7 +153,6 @@
|
||||
{"key": "maxspeed", "value": "ua:urban"},
|
||||
{"key": "maxspeed", "value": "at:rural"},
|
||||
{"key": "maxspeed", "value": "de:rural"},
|
||||
{"key": "maxspeed", "value": "dk:rural"},
|
||||
{"key": "maxspeed", "value": "at:trunk"},
|
||||
{"key": "maxspeed", "value": "cz:trunk"},
|
||||
{"key": "maxspeed", "value": "ro:trunk"},
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
n1 v1 dV c1 t2014-01-01T00:00:00Z i1 utest T x1.02 y1.02
|
||||
n1 v1 dV c1 t2014-01-01T00:00:00Z i1 utest T x1.02 y1.02
|
||||
|
||||
@@ -34,14 +34,11 @@ class MockScriptingEnvironment : public extractor::ScriptingEnvironment
|
||||
void ProcessTurn(extractor::ExtractionTurn &) override final {}
|
||||
void ProcessSegment(extractor::ExtractionSegment &) override final {}
|
||||
|
||||
void ProcessElements(
|
||||
const osmium::memory::Buffer &,
|
||||
const extractor::RestrictionParser &,
|
||||
const extractor::ExtractionRelationContainer &,
|
||||
std::vector<std::pair<const osmium::Node &, extractor::ExtractionNode>> &,
|
||||
std::vector<std::pair<const osmium::Way &, extractor::ExtractionWay>> &,
|
||||
std::vector<std::pair<const osmium::Relation &, extractor::ExtractionRelation>> &,
|
||||
std::vector<extractor::InputConditionalTurnRestriction> &) override final
|
||||
void ProcessElements(const osmium::memory::Buffer &,
|
||||
const extractor::RestrictionParser &,
|
||||
std::vector<std::pair<const osmium::Node &, extractor::ExtractionNode>> &,
|
||||
std::vector<std::pair<const osmium::Way &, extractor::ExtractionWay>> &,
|
||||
std::vector<extractor::InputConditionalTurnRestriction> &) override final
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user