return name and reference separately

This commit is contained in:
karenzshea 2016-09-05 09:01:51 -04:00 committed by Moritz Kobitzsch
parent 938dff011f
commit dcc1b5ab2b
29 changed files with 131 additions and 74 deletions

View File

@ -4,11 +4,13 @@
- includes library guidance.lua that offers preliminary configuration on guidance.
- added left_hand_driving flag in global profile properties
- modified turn penalty function for car profile - better fit to real data
- return `ref` and `name` as separate fields. Do no use ref or destination as fallback for name value
- Guidance
- Handle Access tags for lanes, only considering valid lanes in lane-guidance (think car | car | bike | car)
- API:
- `annotations=true` now returns the data source id for each segment as `datasources`
- Reduced semantic of merge to refer only to merges from a lane onto a motorway-like road
- new `ref` field in the `RouteStep` object. It contains the reference code or name of a way. Previously merged into the `name` property like `name (ref)` and are now separate fields.
- Bugfixes
- Fixed an issue that would result in segfaults for viaroutes with an invalid intermediate segment when u-turns were allowed at the via-location
- Invalid only_* restrictions could result in loss of connectivity. As a fallback, we assume all turns allowed when the restriction is not valid

View File

@ -40,7 +40,7 @@ http://{server}/{service}/{version}/{profile}/{coordinates}[.{format}]?option=va
- `version`: Version of the protocol implemented by the service.
- `profile`: Mode of transportation, is determined by the profile that is used to prepare the data
- `coordinates`: String of format `{longitude},{latitude};{longitude},{latitude}[;{longitude},{latitude} ...]` or `polyline({polyline})`.
- `format`: Only `json` is supportest at the moment. This parameter is optional and defaults to `json`.
- `format`: Only `json` is supported at the moment. This parameter is optional and defaults to `json`.
Passing any `option=value` is optional. `polyline` follows Google's polyline format with precision 5 and can be generated using [this package](https://www.npmjs.com/package/polyline).
To pass parameters to each location some options support an array like encoding:
@ -469,6 +469,7 @@ step.
| geojson | [GeoJSON `LineString`](http://geojson.org/geojson-spec.html#linestring) or [GeoJSON `Point`](http://geojson.org/geojson-spec.html#point) if it is only one coordinate (not wrapped by a GeoJSON feature)|
- `name`: The name of the way along which travel proceeds.
- `ref`: A reference number or code for the way. Optionally included, if ref data is available for the given way.
- `pronunciation`: The pronunciation hint of the way name. Will be `undefined` if there is no pronunciation hit.
- `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
- `mode`: A string signifying the mode of transportation.

View File

@ -15,8 +15,8 @@ Feature: Bike - Street names in instructions
| bc | Your Way | A7 |
When I route I should get
| from | to | route |
| a | c | My Way (A6),Your Way (A7),Your Way (A7) |
| from | to | route | ref |
| a | c | My Way,Your Way,Your Way | A6,A7,A7 |
@unnamed
Scenario: Bike - Use way type to describe unnamed ways

View File

@ -13,8 +13,8 @@ Feature: Bike - Way ref
| ab | Utopia Drive | E7 |
When I route I should get
| from | to | route |
| a | b | Utopia Drive (E7),Utopia Drive (E7) |
| from | to | route | ref |
| a | b | Utopia Drive,Utopia Drive | E7,E7 |
Scenario: Bike - Way with only ref
Given the node map
@ -25,8 +25,8 @@ Feature: Bike - Way ref
| ab | | E7 |
When I route I should get
| from | to | route |
| a | b | E7,E7 |
| from | to | route | ref |
| a | b | {highway:primary},{highway:primary} | E7,E7 |
Scenario: Bike - Way with only name
Given the node map

View File

@ -15,8 +15,8 @@ Feature: Car - Street names in instructions
| bc | Your Way | A1 |
When I route I should get
| from | to | route |
| a | c | My Way,Your Way (A1),Your Way (A1) |
| from | to | route | ref |
| a | c | My Way,Your Way,Your Way | ,A1,A1|
Scenario: Car - A named street with pronunciation
Given the node map
@ -25,15 +25,15 @@ Feature: Car - Street names in instructions
| | c | |
And the ways
| nodes | name |name:pronunciation | ref |
| nodes | name |name:pronunciation | ref |
| ab | My Way | | |
| bd | My Way | meyeway | A1 |
| cd | Your Way | yourewaye | |
When I route I should get
| from | to | route | pronunciations |
| a | d | My Way,My Way (A1) | ,meyeway |
| 1 | c | Your Way,Your Way | yourewaye,yourewaye |
| from | to | route | pronunciations | ref |
| a | d | My Way,My Way | ,meyeway | ,A1 |
| 1 | c | Your Way,Your Way | yourewaye,yourewaye | , |
@todo
Scenario: Car - Use way type to describe unnamed ways

View File

@ -16,7 +16,7 @@ Feature: Foot - Street names in instructions
When I route I should get
| from | to | route |
| a | c | My Way (A6),Your Way (B7),Your Way (B7) |
| a | c | My Way,Your Way,Your Way |
@unnamed
Scenario: Foot - Use way type to describe unnamed ways

View File

@ -14,7 +14,7 @@ Feature: Foot - Way ref
When I route I should get
| from | to | route |
| a | b | Utopia Drive (E7),Utopia Drive (E7) |
| a | b | Utopia Drive,Utopia Drive |
Scenario: Foot - Way with only ref
Given the node map
@ -25,8 +25,8 @@ Feature: Foot - Way ref
| ab | | E7 |
When I route I should get
| from | to | route |
| a | b | E7,E7 |
| from | to | route |
| a | b | {highway:primary},{highway:primary} |
Scenario: Foot - Way with only name
Given the node map

View File

@ -165,8 +165,8 @@ Feature: Slipways and Dedicated Turn Lanes
| qe | secondary_link | Ettlinger Allee | | yes |
When I route I should get
| waypoints | route | turns |
| a,o | Schwarzwaldstrasse (L561),Ettlinger Allee,Ettlinger Allee | depart,turn right,arrive |
| waypoints | route | turns | ref |
| a,o | Schwarzwaldstrasse,Ettlinger Allee,Ettlinger Allee | depart,turn right,arrive | L561,, |
Scenario: Traffic Lights everywhere
#http://map.project-osrm.org/?z=18&center=48.995336%2C8.383813&loc=48.995467%2C8.384548&loc=48.995115%2C8.382761&hl=en&alt=0

View File

@ -29,13 +29,13 @@ Feature: Destination Signs
| qr | QR | | | A1;A2 | yes | |
When I route I should get
| from | to | route | destinations | # |
| a | b | AB (E1),AB (E1) | , | |
| c | d | CD (Berlin),CD (Berlin) | Berlin,Berlin | |
| e | f | EF (A1: Berlin),EF (A1: Berlin) | A1: Berlin,A1: Berlin | |
| g | h | , | A1: Berlin,A1: Berlin | |
| i | j | , | Berlin,Berlin | |
| k | l | KL (E1),KL (E1) | A1: Berlin,A1: Berlin | |
| m | n | MN (A1, A2: Berlin, Hamburg),MN (A1, A2: Berlin, Hamburg) | A1, A2: Berlin, Hamburg,A1, A2: Berlin, Hamburg | |
| o | p | OP,OP | , | guard against mis-tagging |
| q | r | QR (A1, A2),QR (A1, A2) | A1, A2,A1, A2 | |
| from | to | route | destinations | ref | # |
| a | b | AB,AB | , | E1,E1 | |
| c | d | CD,CD | Berlin,Berlin | , | |
| e | f | EF,EF | A1: Berlin,A1: Berlin | , | |
| g | h | , | A1: Berlin,A1: Berlin | , | |
| i | j | , | Berlin,Berlin | , | |
| k | l | KL,KL | A1: Berlin,A1: Berlin | E1,E1 | |
| m | n | MN,MN | A1, A2: Berlin, Hamburg,A1, A2: Berlin, Hamburg | , | |
| o | p | OP,OP | , | , | guard against mis-tagging |
| q | r | QR,QR | A1, A2,A1, A2 | , | |

View File

@ -283,9 +283,9 @@ Feature: Basic Roundabout
| dmg | roundabout | | trunk_link | yes | |
When I route I should get
| waypoints | route | turns |
| a,e | crescent (US 130),crescent (US 130),crescent (US 130) | depart,roundabout-exit-3,arrive |
| j,l | NJ 38,NJ 38,NJ 38 | depart,roundabout-exit-2,arrive |
| waypoints | route | turns | ref |
| a,e | crescent,crescent,crescent | depart,roundabout-exit-3,arrive | US 130,US 130,US 130 |
| j,l | ,, | depart,roundabout-exit-2,arrive | NJ 38,NJ 38,NJ 38 |
Scenario: Double Roundabout with through-lane
#http://map.project-osrm.org/?z=18&center=38.911752%2C-77.048667&loc=38.912003%2C-77.050831&loc=38.909277%2C-77.042516&hl=en&alt=0

View File

@ -28,8 +28,8 @@ Feature: Suppress New Names on dedicated Suffices
| bc | 42 S | 101 |
When I route I should get
| waypoints | route | turns |
| a,c | 42 N,42 S (101) | depart,arrive |
| waypoints | route | turns | ref |
| a,c | 42 N,42 S | depart,arrive | ,101 |
Scenario: Prefix Change
Given the node map
@ -67,8 +67,8 @@ Feature: Suppress New Names on dedicated Suffices
| bc | East 42 | |
When I route I should get
| waypoints | route | turns |
| a,c | West 42 (101),East 42 | depart,arrive |
| waypoints | route | turns | ref |
| a,c | West 42,East 42 | depart,arrive | 101, |
Scenario: Suffix To Suffix - Turn
Given the node map

View File

@ -32,8 +32,8 @@ Feature: Suppressed Turns
| ef | motorway | highway | A1 |
When I route I should get
| waypoints | route | turns |
| a,f | highway (A1),highway (A1) | depart,arrive |
| waypoints | route | turns | ref |
| a,f | highway,highway | depart,arrive | A1,A1 |
Scenario: Don't Announce Turn on following major road class -- service

View File

@ -139,6 +139,10 @@ module.exports = function () {
return this.extractInstructionList(instructions, s => s.name);
};
this.refList = (instructions) => {
return this.extractInstructionList(instructions, s => s.ref || '');
};
this.pronunciationList = (instructions) => {
return this.extractInstructionList(instructions, s => s.pronunciation || '');
};

View File

@ -34,7 +34,7 @@ module.exports = function () {
var afterRequest = (err, res, body) => {
if (err) return cb(err);
if (body && body.length) {
let destinations, pronunciations, instructions, bearings, turns, modes, times,
let destinations, pronunciations, instructions, refs, bearings, turns, modes, times,
distances, summary, intersections, lanes;
let json = JSON.parse(body);
@ -44,6 +44,7 @@ module.exports = function () {
if (hasRoute) {
instructions = this.wayList(json.routes[0]);
pronunciations = this.pronunciationList(json.routes[0]);
refs = this.refList(json.routes[0]);
destinations = this.destinationsList(json.routes[0]);
bearings = this.bearingList(json.routes[0]);
turns = this.turnList(json.routes[0]);
@ -128,6 +129,7 @@ module.exports = function () {
if (headers.has(key)) got[key] = instructions ? value : '';
};
putValue('ref', refs);
putValue('bearing', bearings);
putValue('turns', turns);
putValue('modes', modes);

View File

@ -152,6 +152,8 @@ class BaseDataFacade
virtual std::string GetNameForID(const unsigned name_id) const = 0;
virtual std::string GetRefForID(const unsigned name_id) const = 0;
virtual std::string GetPronunciationForID(const unsigned name_id) const = 0;
virtual std::string GetDestinationsForID(const unsigned name_id) const = 0;

View File

@ -636,6 +636,15 @@ class InternalDataFacade final : public BaseDataFacade
return result;
}
std::string GetRefForID(const unsigned name_id) const override final
{
// We store the ref after the name, destination and pronunciation of a street.
// We do this to get around the street length limit of 255 which would hit
// if we concatenate these. Order (see extractor_callbacks):
// name (0), destination (1), pronunciation (2), ref (3)
return GetNameForID(name_id + 3);
}
std::string GetPronunciationForID(const unsigned name_id) const override final
{
// We store the pronunciation after the name and destination of a street.

View File

@ -707,12 +707,21 @@ class SharedDataFacade final : public BaseDataFacade
return result;
}
std::string GetRefForID(const unsigned name_id) const override final
{
// We store the ref after the name, destination and pronunciation of a street.
// We do this to get around the street length limit of 255 which would hit
// if we concatenate these. Order (see extractor_callbacks):
// name (0), destination (1), pronunciation (2), ref (3)
return GetNameForID(name_id + 3);
}
std::string GetPronunciationForID(const unsigned name_id) const override final
{
// We store the pronunciation after the name and destination of a street.
// We do this to get around the street length limit of 255 which would hit
// if we concatenate these. Order (see extractor_callbacks):
// name (0), destination (1), pronunciation (2)
// name (0), destination (1), pronunciation (2), ref (3)
return GetNameForID(name_id + 2);
}
@ -721,7 +730,7 @@ class SharedDataFacade final : public BaseDataFacade
// We store the destination after the name of a street.
// We do this to get around the street length limit of 255 which would hit
// if we concatenate these. Order (see extractor_callbacks):
// name (0), destination (1), pronunciation (2)
// name (0), destination (1), pronunciation (2), ref (3)
return GetNameForID(name_id + 1);
}

View File

@ -103,12 +103,14 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
{
BOOST_ASSERT(segment_duration >= 0);
const auto name = facade.GetNameForID(step_name_id);
const auto ref = facade.GetRefForID(step_name_id);
const auto pronunciation = facade.GetPronunciationForID(step_name_id);
const auto destinations = facade.GetDestinationsForID(step_name_id);
const auto distance = leg_geometry.segment_distances[segment_index];
steps.push_back(RouteStep{step_name_id,
std::move(name),
std::move(ref),
std::move(pronunciation),
std::move(destinations),
NO_ROTARY_NAME,
@ -168,6 +170,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{step_name_id,
facade.GetNameForID(step_name_id),
facade.GetRefForID(step_name_id),
facade.GetPronunciationForID(step_name_id),
facade.GetDestinationsForID(step_name_id),
NO_ROTARY_NAME,
@ -194,6 +197,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
steps.push_back(RouteStep{source_node.name_id,
facade.GetNameForID(source_node.name_id),
facade.GetRefForID(source_node.name_id),
facade.GetPronunciationForID(source_node.name_id),
facade.GetDestinationsForID(source_node.name_id),
NO_ROTARY_NAME,
@ -229,6 +233,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
BOOST_ASSERT(!leg_geometry.locations.empty());
steps.push_back(RouteStep{target_node.name_id,
facade.GetNameForID(target_node.name_id),
facade.GetRefForID(target_node.name_id),
facade.GetPronunciationForID(target_node.name_id),
facade.GetDestinationsForID(target_node.name_id),
NO_ROTARY_NAME,

View File

@ -25,10 +25,10 @@ namespace guidance
// a --> b --> c
// this struct saves the information of the segment b,c.
// Notable exceptions are Departure and Arrival steps.
// Departue: s --> a --> b. Represents the segment s,a with location being s.
// Departure: s --> a --> b. Represents the segment s,a with location being s.
// Arrive: a --> b --> t. The segment (b,t) is already covered by the previous segment.
// A represenetation of intermediate intersections
// A representation of intermediate intersections
struct Intersection
{
static const constexpr std::size_t NO_INDEX = std::numeric_limits<std::size_t>::max();
@ -58,6 +58,7 @@ struct RouteStep
{
unsigned name_id;
std::string name;
std::string ref;
std::string pronunciation;
std::string destinations;
std::string rotary_name;
@ -80,6 +81,7 @@ inline RouteStep getInvalidRouteStep()
"",
"",
"",
"",
0,
0,
TRAVEL_MODE_INACCESSIBLE,

View File

@ -33,6 +33,7 @@ struct ExtractionWay
is_startpoint = true;
is_access_restricted = false;
name.clear();
ref.clear();
pronunciation.clear();
destinations.clear();
forward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
@ -53,6 +54,7 @@ struct ExtractionWay
double backward_speed;
double duration;
std::string name;
std::string ref;
std::string pronunciation;
std::string destinations;
std::string turn_lanes_forward;

View File

@ -16,6 +16,21 @@ class Node;
class Way;
}
namespace std
{
template <> struct hash<std::tuple<std::string, std::string, std::string>>
{
std::size_t operator()(const std::tuple<std::string, std::string, std::string> &mk) const noexcept
{
std::size_t seed = 0;
boost::hash_combine(seed, std::get<0>(mk));
boost::hash_combine(seed, std::get<1>(mk));
boost::hash_combine(seed, std::get<2>(mk));
return seed;
}
};
}
namespace osrm
{
namespace extractor
@ -27,7 +42,7 @@ struct ExtractionNode;
struct ExtractionWay;
/**
* This class is uses by the extractor with the results of the
* This class is used by the extractor with the results of the
* osmium based parsing and the customization through the lua profile.
*
* It mediates between the multi-threaded extraction process and the external memory containers.
@ -37,9 +52,9 @@ class ExtractorCallbacks
{
private:
// used to deduplicate street names and street destinations: actually maps to name ids
using MapKey = std::pair<std::string, std::string>;
using MapKey = std::tuple<std::string, std::string, std::string>;
using MapVal = unsigned;
std::unordered_map<MapKey, MapVal, boost::hash<MapKey>> string_map;
std::unordered_map<MapKey, MapVal> string_map;
guidance::LaneDescriptionMap lane_description_map;
ExtractionContainers &external_memory;

View File

@ -211,19 +211,20 @@ function way_function (way, result)
local bicycle = way:get_value_by_key("bicycle")
-- name
if ref and "" ~= ref and name and "" ~= name then
result.name = name .. " (" .. ref .. ")"
elseif ref and "" ~= ref then
result.name = ref
elseif name and "" ~= name then
if name and "" ~= name then
result.name = name
-- TODO find a better solution for encoding way type
elseif fallback_names and highway then
-- if no name exists, use way type
-- this encoding scheme is excepted to be a temporary solution
-- this encoding scheme is expected to be a temporary solution
result.name = "{highway:"..highway.."}"
end
-- ref
if ref and "" ~= ref then
result.ref = ref
end
-- roundabout handling
if junction and "roundabout" == junction then
result.roundabout = true

View File

@ -387,14 +387,14 @@ function way_function (way, result)
local has_name = name and "" ~= name
local has_pronunciation = pronunciation and "" ~= pronunciation
if has_name and has_ref then
result.name = name .. " (" .. ref .. ")"
elseif has_ref then
result.name = ref
elseif has_name then
if has_name then
result.name = name
end
if has_ref then
result.ref = ref
end
if has_pronunciation then
result.pronunciation = pronunciation
end
@ -456,10 +456,6 @@ function way_function (way, result)
local destination = get_destination(way)
local has_destination = destination and "" ~= destination
if has_destination and has_name and not has_ref then
result.name = name .. " (" .. destination .. ")"
end
result.destinations = destination
end
end

View File

@ -150,16 +150,15 @@ function way_function (way, result)
local surface = way:get_value_by_key("surface")
-- name
if ref and "" ~= ref and name and "" ~= name then
result.name = name .. " (" .. ref .. ")"
elseif ref and "" ~= ref then
result.name = ref
elseif name and "" ~= name then
if name and "" ~= name then
result.name = name
elseif highway and fallback_names then
result.name = "{highway:"..highway.."}" -- if no name exists, use way type
-- this encoding scheme is excepted to be a temporary solution
end
if ref and "" ~= ref then
result.ref = ref
end
-- roundabouts
if "roundabout" == junction then

View File

@ -235,6 +235,7 @@ util::json::Object makeRouteStep(guidance::RouteStep step, util::json::Value geo
route_step.values["distance"] = std::round(step.distance * 10) / 10.;
route_step.values["duration"] = std::round(step.duration * 10) / 10.;
route_step.values["name"] = std::move(step.name);
if (!step.ref.empty()) route_step.values["ref"] = std::move(step.ref);
if (!step.pronunciation.empty())
route_step.values["pronunciation"] = std::move(step.pronunciation);
if (!step.destinations.empty())

View File

@ -52,6 +52,8 @@ inline void forwardStepSignage(RouteStep &destination, const RouteStep &origin)
destination.name = origin.name;
destination.pronunciation = origin.pronunciation;
destination.destinations = origin.destinations;
destination.destinations = origin.destinations;
destination.ref = origin.ref;
}
inline bool choiceless(const RouteStep &step, const RouteStep &previous)

View File

@ -35,9 +35,7 @@ ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containe
: external_memory(extraction_containers)
{
// we reserved 0, 1, 2 for the empty case
string_map[MapKey("", "")] = 0;
// The map should be empty before we start initializing it
string_map[MapKey("", "", "")] = 0;
lane_description_map[TurnLaneDescription()] = 0;
}
@ -235,16 +233,15 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
}
};
// Deduplicates street names and street destination names based on the street_map map.
// Deduplicates street names, destination names and refs based on the string_map map.
// In case we do not already store the name, inserts (name, id) tuple and return id.
// Otherwise fetches the id based on the name and returns it without insertion.
const auto turn_lane_id_forward = requestId(parsed_way.turn_lanes_forward);
const auto turn_lane_id_backward = requestId(parsed_way.turn_lanes_backward);
const constexpr auto MAX_STRING_LENGTH = 255u;
// Get the unique identifier for the street name
// Get the unique identifier for the street name and destination
const auto name_iterator = string_map.find(MapKey(parsed_way.name, parsed_way.destinations));
// Get the unique identifier for the street name, destination, and ref
const auto name_iterator = string_map.find(MapKey(parsed_way.name, parsed_way.destinations, parsed_way.ref));
unsigned name_id = EMPTY_NAMEID;
if (string_map.end() == name_iterator)
{
@ -253,6 +250,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
std::min<unsigned>(MAX_STRING_LENGTH, parsed_way.destinations.size());
const auto pronunciation_length =
std::min<unsigned>(MAX_STRING_LENGTH, parsed_way.pronunciation.size());
const auto ref_length = std::min<unsigned>(MAX_STRING_LENGTH, parsed_way.ref.size());
// name_offsets already has an offset of a new name, take the offset index as the name id
name_id = external_memory.name_offsets.size() - 1;
@ -275,7 +273,12 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
std::back_inserter(external_memory.name_char_data));
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
auto k = MapKey{parsed_way.name, parsed_way.destinations};
std::copy(parsed_way.ref.c_str(),
parsed_way.ref.c_str() + ref_length,
std::back_inserter(external_memory.name_char_data));
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
auto k = MapKey{parsed_way.name, parsed_way.destinations, parsed_way.ref};
auto v = MapVal{name_id};
string_map.emplace(std::move(k), std::move(v));
}

View File

@ -175,6 +175,7 @@ void LuaScriptingEnvironment::InitContext(LuaScriptingContext &context)
.def_readwrite("forward_speed", &ExtractionWay::forward_speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("ref", &ExtractionWay::ref)
.def_readwrite("pronunciation", &ExtractionWay::pronunciation)
.def_readwrite("destinations", &ExtractionWay::destinations)
.def_readwrite("roundabout", &ExtractionWay::roundabout)

View File

@ -175,6 +175,7 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
bool IsCoreNode(const NodeID /* id */) const override { return false; }
unsigned GetNameIndexFromEdgeID(const unsigned /* id */) const override { return 0; }
std::string GetNameForID(const unsigned /* name_id */) const override { return ""; }
std::string GetRefForID(const unsigned /* name_id */) const override { return ""; }
std::string GetPronunciationForID(const unsigned /* name_id */) const override { return ""; }
std::string GetDestinationsForID(const unsigned /* name_id */) const override { return ""; }
std::size_t GetCoreSize() const override { return 0; }