Implements Exit Numbers + Names (junction:ref
way tag for now)
This commit is contained in:
parent
6d78c11fd2
commit
7d900e3b5a
@ -11,6 +11,9 @@
|
||||
- new parameter `approaches` for `route`, `table`, `trip` and `nearest` requests. This parameter keep waypoints on the curb side.
|
||||
'approaches' accepts both 'curb' and 'unrestricted' values.
|
||||
Note : the curb side depend on the `ProfileProperties::left_hand_driving`, it's a global property set once by the profile. If you are working with a planet dataset, the api will be wrong in some countries, and right in others.
|
||||
- Support for exits numbers and names. New member `exits` in `RouteStep`, based on `junction:ref` on ways
|
||||
- Profiles:
|
||||
- `result.exits` allows you to set a way's exit numbers and names, see [`junction:ref`](http://wiki.openstreetmap.org/wiki/Proposed_features/junction_details)
|
||||
- NodeJs Bindings
|
||||
- new parameter `approaches` for `route`, `table`, `trip` and `nearest` requests.
|
||||
- Tools
|
||||
|
@ -581,6 +581,7 @@ step.
|
||||
- `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.
|
||||
- `exits`: The exit numbers or names of the way. Will be `undefined` if there are no exit numbers or names.
|
||||
- `mode`: A string signifying the mode of transportation.
|
||||
- `maneuver`: A `StepManeuver` object representing the maneuver.
|
||||
- `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver
|
||||
|
@ -67,6 +67,8 @@ roundabout | Boolean | Is this part of a roundabou
|
||||
circular | Boolean | Is this part of a non-roundabout circular junction?
|
||||
name | String | Name of the way
|
||||
ref | String | Road number
|
||||
destinations | String | The road's destinations
|
||||
exits | String | The ramp's exit numbers or names
|
||||
pronunciation | String | Name pronunciation
|
||||
road_classification.motorway_class | Boolean | Guidance: way is a motorway
|
||||
road_classification.link_class | Boolean | Guidance: way is a slip/link road
|
||||
|
28
features/guidance/exit-numbers-names.feature
Normal file
28
features/guidance/exit-numbers-names.feature
Normal file
@ -0,0 +1,28 @@
|
||||
@routing @guidance
|
||||
Feature: Exit Numbers and Names
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 10 meters
|
||||
|
||||
Scenario: Exit number on the way after the motorway junction
|
||||
Given the node map
|
||||
"""
|
||||
a . . b . c . . d
|
||||
` e . . f
|
||||
"""
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| b | motorway_junction |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | junction:ref |
|
||||
| abcd | motorway | MainRoad | |
|
||||
| be | motorway_link | ExitRamp | 3 |
|
||||
| ef | motorway_link | ExitRamp | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | exits |
|
||||
| a,f | MainRoad,ExitRamp,ExitRamp | depart,off ramp slight right,arrive | ,3, |
|
||||
|
@ -155,6 +155,10 @@ module.exports = function () {
|
||||
return this.extractInstructionList(instructions, s => s.destinations || '');
|
||||
};
|
||||
|
||||
this.exitsList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, s => s.exits || '');
|
||||
};
|
||||
|
||||
this.reverseBearing = (bearing) => {
|
||||
if (bearing >= 180)
|
||||
return bearing - 180.;
|
||||
|
@ -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, refs, bearings, turns, modes, times,
|
||||
let destinations, exits, pronunciations, instructions, refs, bearings, turns, modes, times,
|
||||
distances, summary, intersections, lanes, locations, annotation, weight_name, weights, approaches;
|
||||
|
||||
let json = JSON.parse(body);
|
||||
@ -48,6 +48,7 @@ module.exports = function () {
|
||||
pronunciations = this.pronunciationList(json.routes[0]);
|
||||
refs = this.refList(json.routes[0]);
|
||||
destinations = this.destinationsList(json.routes[0]);
|
||||
exits = this.exitsList(json.routes[0]);
|
||||
bearings = this.bearingList(json.routes[0]);
|
||||
turns = this.turnList(json.routes[0]);
|
||||
intersections = this.intersectionList(json.routes[0]);
|
||||
@ -177,6 +178,7 @@ module.exports = function () {
|
||||
putValue('distances', distances);
|
||||
putValue('pronunciations', pronunciations);
|
||||
putValue('destinations', destinations);
|
||||
putValue('exits', exits);
|
||||
putValue('weight_name', weight_name);
|
||||
putValue('weights', weights);
|
||||
putValue('weight', weight);
|
||||
|
@ -14,6 +14,7 @@ Feature: Testbot - Check assigning nil values
|
||||
result.name = nil
|
||||
result.ref = nil
|
||||
result.destinations = nil
|
||||
result.exits = nil
|
||||
result.pronunciation = nil
|
||||
result.turn_lanes_forward = nil
|
||||
result.turn_lanes_backward = nil
|
||||
|
@ -808,6 +808,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
return m_name_table.GetDestinationsForID(id);
|
||||
}
|
||||
|
||||
StringView GetExitsForID(const NameID id) const override final
|
||||
{
|
||||
return m_name_table.GetExitsForID(id);
|
||||
}
|
||||
|
||||
StringView GetDatasourceName(const DatasourceID id) const override final
|
||||
{
|
||||
return m_datasources->GetSourceName(id);
|
||||
|
@ -158,6 +158,8 @@ class BaseDataFacade
|
||||
|
||||
virtual StringView GetDestinationsForID(const NameID id) const = 0;
|
||||
|
||||
virtual StringView GetExitsForID(const NameID id) const = 0;
|
||||
|
||||
virtual std::string GetTimestamp() const = 0;
|
||||
|
||||
virtual bool GetContinueStraightDefault() const = 0;
|
||||
|
@ -114,6 +114,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
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 exits = facade.GetExitsForID(step_name_id);
|
||||
const auto distance = leg_geometry.segment_distances[segment_index];
|
||||
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
@ -121,6 +122,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
ref.to_string(),
|
||||
pronunciation.to_string(),
|
||||
destinations.to_string(),
|
||||
exits.to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
segment_duration / 10.,
|
||||
@ -196,6 +198,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
facade.GetRefForID(step_name_id).to_string(),
|
||||
facade.GetPronunciationForID(step_name_id).to_string(),
|
||||
facade.GetDestinationsForID(step_name_id).to_string(),
|
||||
facade.GetExitsForID(step_name_id).to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
@ -237,6 +240,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
facade.GetRefForID(source_name_id).to_string(),
|
||||
facade.GetPronunciationForID(source_name_id).to_string(),
|
||||
facade.GetDestinationsForID(source_name_id).to_string(),
|
||||
facade.GetExitsForID(source_name_id).to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
@ -275,6 +279,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
facade.GetRefForID(target_name_id).to_string(),
|
||||
facade.GetPronunciationForID(target_name_id).to_string(),
|
||||
facade.GetDestinationsForID(target_name_id).to_string(),
|
||||
facade.GetExitsForID(target_name_id).to_string(),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
ZERO_DURATION,
|
||||
|
@ -130,8 +130,14 @@ inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
|
||||
|
||||
// ok, bite the sour grape and check the strings already
|
||||
else
|
||||
return !util::guidance::requiresNameAnnounced(
|
||||
lhs.name, lhs.ref, lhs.pronunciation, rhs.name, rhs.ref, rhs.pronunciation);
|
||||
return !util::guidance::requiresNameAnnounced(lhs.name,
|
||||
lhs.ref,
|
||||
lhs.pronunciation,
|
||||
lhs.exits,
|
||||
rhs.name,
|
||||
rhs.ref,
|
||||
rhs.pronunciation,
|
||||
rhs.exits);
|
||||
}
|
||||
|
||||
// alias for readability, both turn right | left
|
||||
|
@ -62,6 +62,7 @@ struct RouteStep
|
||||
std::string ref;
|
||||
std::string pronunciation;
|
||||
std::string destinations;
|
||||
std::string exits;
|
||||
std::string rotary_name;
|
||||
std::string rotary_pronunciation;
|
||||
double duration; // duration in seconds
|
||||
@ -114,6 +115,7 @@ inline void RouteStep::Invalidate()
|
||||
ref.clear();
|
||||
pronunciation.clear();
|
||||
destinations.clear();
|
||||
exits.clear();
|
||||
rotary_name.clear();
|
||||
rotary_pronunciation.clear();
|
||||
duration = 0;
|
||||
@ -178,6 +180,7 @@ inline RouteStep &RouteStep::AdaptStepSignage(const RouteStep &origin)
|
||||
name = origin.name;
|
||||
pronunciation = origin.pronunciation;
|
||||
destinations = origin.destinations;
|
||||
exits = origin.exits;
|
||||
ref = origin.ref;
|
||||
|
||||
return *this;
|
||||
|
@ -53,6 +53,7 @@ struct ExtractionWay
|
||||
ref.clear();
|
||||
pronunciation.clear();
|
||||
destinations.clear();
|
||||
exits.clear();
|
||||
forward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
turn_lanes_forward.clear();
|
||||
@ -69,6 +70,8 @@ struct ExtractionWay
|
||||
const char *GetRef() const { return ref.c_str(); }
|
||||
void SetDestinations(const char *value) { detail::maybeSetString(destinations, value); }
|
||||
const char *GetDestinations() const { return destinations.c_str(); }
|
||||
void SetExits(const char *value) { detail::maybeSetString(exits, value); }
|
||||
const char *GetExits() const { return exits.c_str(); }
|
||||
void SetPronunciation(const char *value) { detail::maybeSetString(pronunciation, value); }
|
||||
const char *GetPronunciation() const { return pronunciation.c_str(); }
|
||||
void SetTurnLanesForward(const char *value)
|
||||
@ -96,6 +99,7 @@ struct ExtractionWay
|
||||
std::string ref;
|
||||
std::string pronunciation;
|
||||
std::string destinations;
|
||||
std::string exits;
|
||||
std::string turn_lanes_forward;
|
||||
std::string turn_lanes_backward;
|
||||
guidance::RoadClassification road_classification;
|
||||
|
@ -18,10 +18,10 @@ class Way;
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <> struct hash<std::tuple<std::string, std::string, std::string, std::string>>
|
||||
template <> struct hash<std::tuple<std::string, std::string, std::string, std::string, std::string>>
|
||||
{
|
||||
std::size_t
|
||||
operator()(const std::tuple<std::string, std::string, std::string, std::string> &mk) const
|
||||
std::size_t operator()(
|
||||
const std::tuple<std::string, std::string, std::string, std::string, std::string> &mk) const
|
||||
noexcept
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
@ -29,6 +29,7 @@ template <> struct hash<std::tuple<std::string, std::string, std::string, std::s
|
||||
boost::hash_combine(seed, std::get<1>(mk));
|
||||
boost::hash_combine(seed, std::get<2>(mk));
|
||||
boost::hash_combine(seed, std::get<3>(mk));
|
||||
boost::hash_combine(seed, std::get<4>(mk));
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
@ -55,9 +56,9 @@ struct ProfileProperties;
|
||||
class ExtractorCallbacks
|
||||
{
|
||||
private:
|
||||
// used to deduplicate street names, refs, destinations, pronunciation: actually maps to name
|
||||
// ids
|
||||
using MapKey = std::tuple<std::string, std::string, std::string, std::string>;
|
||||
// used to deduplicate street names, refs, destinations, pronunciation, exits:
|
||||
// actually maps to name ids
|
||||
using MapKey = std::tuple<std::string, std::string, std::string, std::string, std::string>;
|
||||
using MapVal = unsigned;
|
||||
std::unordered_map<MapKey, MapVal> string_map;
|
||||
guidance::LaneDescriptionMap lane_description_map;
|
||||
|
@ -46,7 +46,8 @@ inline void print(const engine::guidance::RouteStep &step)
|
||||
std::cout << ")";
|
||||
}
|
||||
std::cout << "] name[" << step.name_id << "]: " << step.name << " Ref: " << step.ref
|
||||
<< " Pronunciation: " << step.pronunciation << "Destination: " << step.destinations;
|
||||
<< " Pronunciation: " << step.pronunciation << "Destination: " << step.destinations
|
||||
<< "Exits: " << step.exits;
|
||||
}
|
||||
|
||||
inline void print(const std::vector<engine::guidance::RouteStep> &steps)
|
||||
|
@ -44,9 +44,11 @@ template <typename SuffixTable>
|
||||
inline bool requiresNameAnnounced(const std::string &from_name,
|
||||
const std::string &from_ref,
|
||||
const std::string &from_pronunciation,
|
||||
const std::string &from_exits,
|
||||
const std::string &to_name,
|
||||
const std::string &to_ref,
|
||||
const std::string &to_pronunciation,
|
||||
const std::string &to_exits,
|
||||
const SuffixTable &suffix_table)
|
||||
{
|
||||
// first is empty and the second is not
|
||||
@ -128,17 +130,20 @@ inline bool requiresNameAnnounced(const std::string &from_name,
|
||||
(!from_name.empty() && from_ref.empty() && to_name.empty() && !to_ref.empty());
|
||||
|
||||
const auto pronunciation_changes = from_pronunciation != to_pronunciation;
|
||||
const auto exits_change = from_exits != to_exits;
|
||||
|
||||
return !obvious_change || needs_announce || pronunciation_changes;
|
||||
return !obvious_change || needs_announce || pronunciation_changes || exits_change;
|
||||
}
|
||||
|
||||
// Overload without suffix checking
|
||||
inline bool requiresNameAnnounced(const std::string &from_name,
|
||||
const std::string &from_ref,
|
||||
const std::string &from_pronunciation,
|
||||
const std::string &from_exits,
|
||||
const std::string &to_name,
|
||||
const std::string &to_ref,
|
||||
const std::string &to_pronunciation)
|
||||
const std::string &to_pronunciation,
|
||||
const std::string &to_exits)
|
||||
{
|
||||
// Dummy since we need to provide a SuffixTable but do not have the data for it.
|
||||
// (Guidance Post-Processing does not keep the suffix table around at the moment)
|
||||
@ -148,8 +153,15 @@ inline bool requiresNameAnnounced(const std::string &from_name,
|
||||
bool isSuffix(const std::string &) const { return false; }
|
||||
} static const table;
|
||||
|
||||
return requiresNameAnnounced(
|
||||
from_name, from_ref, from_pronunciation, to_name, to_ref, to_pronunciation, table);
|
||||
return requiresNameAnnounced(from_name,
|
||||
from_ref,
|
||||
from_pronunciation,
|
||||
from_exits,
|
||||
to_name,
|
||||
to_ref,
|
||||
to_pronunciation,
|
||||
to_exits,
|
||||
table);
|
||||
}
|
||||
|
||||
inline bool requiresNameAnnounced(const NameID from_name_id,
|
||||
@ -163,9 +175,13 @@ inline bool requiresNameAnnounced(const NameID from_name_id,
|
||||
return requiresNameAnnounced(name_table.GetNameForID(from_name_id).to_string(),
|
||||
name_table.GetRefForID(from_name_id).to_string(),
|
||||
name_table.GetPronunciationForID(from_name_id).to_string(),
|
||||
name_table.GetExitsForID(from_name_id).to_string(),
|
||||
//
|
||||
name_table.GetNameForID(to_name_id).to_string(),
|
||||
name_table.GetRefForID(to_name_id).to_string(),
|
||||
name_table.GetPronunciationForID(to_name_id).to_string(),
|
||||
name_table.GetExitsForID(to_name_id).to_string(),
|
||||
//
|
||||
suffix_table);
|
||||
// FIXME: converts StringViews to strings since the name change heuristics mutates in place
|
||||
}
|
||||
@ -180,8 +196,11 @@ inline bool requiresNameAnnounced(const NameID from_name_id,
|
||||
return requiresNameAnnounced(name_table.GetNameForID(from_name_id).to_string(),
|
||||
name_table.GetRefForID(from_name_id).to_string(),
|
||||
name_table.GetPronunciationForID(from_name_id).to_string(),
|
||||
name_table.GetExitsForID(from_name_id).to_string(),
|
||||
//
|
||||
name_table.GetNameForID(to_name_id).to_string(),
|
||||
name_table.GetRefForID(to_name_id).to_string(),
|
||||
name_table.GetExitsForID(to_name_id).to_string(),
|
||||
name_table.GetPronunciationForID(to_name_id).to_string());
|
||||
// FIXME: converts StringViews to strings since the name change heuristics mutates in place
|
||||
}
|
||||
|
@ -33,9 +33,9 @@ class NameTable
|
||||
// This class provides a limited view over all the string data we serialize out.
|
||||
// The following functions are a subset of what is available.
|
||||
// See the data facades for they provide full access to this serialized string data.
|
||||
// (at time of writing this: get{Name,Ref,Pronunciation,Destinations}ForID(name_id);)
|
||||
util::StringView GetNameForID(const NameID id) const;
|
||||
util::StringView GetDestinationsForID(const NameID id) const;
|
||||
util::StringView GetExitsForID(const NameID id) const;
|
||||
util::StringView GetRefForID(const NameID id) const;
|
||||
util::StringView GetPronunciationForID(const NameID id) const;
|
||||
|
||||
|
@ -347,7 +347,7 @@ function way_function(way, result)
|
||||
-- check whether forward/backward directions are routable
|
||||
'handle_oneway',
|
||||
|
||||
-- check whether forward/backward directions are routable
|
||||
-- check a road's destination
|
||||
'handle_destinations',
|
||||
|
||||
-- check whether we're using a special transport mode
|
||||
|
@ -32,6 +32,7 @@ function Handlers.handle_names(way,result,data,profile)
|
||||
local name = way:get_value_by_key("name")
|
||||
local pronunciation = way:get_value_by_key("name:pronunciation")
|
||||
local ref = way:get_value_by_key("ref")
|
||||
local exits = way:get_value_by_key("junction:ref")
|
||||
|
||||
-- Set the name that will be used for instructions
|
||||
if name then
|
||||
@ -45,6 +46,10 @@ function Handlers.handle_names(way,result,data,profile)
|
||||
if pronunciation then
|
||||
result.pronunciation = pronunciation
|
||||
end
|
||||
|
||||
if exits then
|
||||
result.exits = exits
|
||||
end
|
||||
end
|
||||
|
||||
-- junctions
|
||||
|
@ -250,6 +250,8 @@ util::json::Object makeRouteStep(guidance::RouteStep step, util::json::Value geo
|
||||
route_step.values["pronunciation"] = std::move(step.pronunciation);
|
||||
if (!step.destinations.empty())
|
||||
route_step.values["destinations"] = std::move(step.destinations);
|
||||
if (!step.exits.empty())
|
||||
route_step.values["exits"] = std::move(step.exits);
|
||||
if (!step.rotary_name.empty())
|
||||
{
|
||||
route_step.values["rotary_name"] = std::move(step.rotary_name);
|
||||
|
@ -120,7 +120,8 @@ ExtractionContainers::ExtractionContainers()
|
||||
// Check if stxxl can be instantiated
|
||||
stxxl::vector<unsigned> dummy_vector;
|
||||
|
||||
// Insert four empty strings offsets for name, ref, destination and pronunciation
|
||||
// Insert four empty strings offsets for name, ref, destination, pronunciation, and exits
|
||||
name_offsets.push_back(0);
|
||||
name_offsets.push_back(0);
|
||||
name_offsets.push_back(0);
|
||||
name_offsets.push_back(0);
|
||||
|
@ -39,8 +39,8 @@ ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containe
|
||||
fallback_to_duration(properties.fallback_to_duration),
|
||||
force_split_edges(properties.force_split_edges)
|
||||
{
|
||||
// we reserved 0, 1, 2, 3 for the empty case
|
||||
string_map[MapKey("", "", "", "")] = 0;
|
||||
// we reserved 0, 1, 2, 3, 4 for the empty case
|
||||
string_map[MapKey("", "", "", "", "")] = 0;
|
||||
lane_description_map.data[TurnLaneDescription()] = 0;
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
return lane_description_map.ConcurrentFindOrAdd(lane_description);
|
||||
};
|
||||
|
||||
// Deduplicates street names, refs, destinations, pronunciation based on the string_map.
|
||||
// Deduplicates street names, refs, destinations, pronunciation, exits.
|
||||
// In case we do not already store the key, inserts (key, 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);
|
||||
@ -263,14 +263,17 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
const auto road_classification = parsed_way.road_classification;
|
||||
|
||||
// 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, parsed_way.pronunciation));
|
||||
const auto name_iterator = string_map.find(MapKey(parsed_way.name,
|
||||
parsed_way.destinations,
|
||||
parsed_way.ref,
|
||||
parsed_way.pronunciation,
|
||||
parsed_way.exits));
|
||||
NameID name_id = EMPTY_NAMEID;
|
||||
if (string_map.end() == name_iterator)
|
||||
{
|
||||
// name_offsets has a sentinel element with the total name data size
|
||||
// take the sentinels index as the name id of the new name data pack
|
||||
// (name [name_id], destination [+1], pronunciation [+2], ref [+3])
|
||||
// (name [name_id], destination [+1], pronunciation [+2], ref [+3], exits [+4])
|
||||
name_id = external_memory.name_offsets.size() - 1;
|
||||
|
||||
std::copy(parsed_way.name.begin(),
|
||||
@ -293,8 +296,16 @@ 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, parsed_way.ref, parsed_way.pronunciation};
|
||||
std::copy(parsed_way.exits.begin(),
|
||||
parsed_way.exits.end(),
|
||||
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,
|
||||
parsed_way.pronunciation,
|
||||
parsed_way.exits};
|
||||
auto v = MapVal{name_id};
|
||||
string_map.emplace(std::move(k), std::move(v));
|
||||
}
|
||||
|
@ -330,6 +330,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
sol::property(&ExtractionWay::GetPronunciation, &ExtractionWay::SetPronunciation),
|
||||
"destinations",
|
||||
sol::property(&ExtractionWay::GetDestinations, &ExtractionWay::SetDestinations),
|
||||
"exits",
|
||||
sol::property(&ExtractionWay::GetExits, &ExtractionWay::SetExits),
|
||||
"turn_lanes_forward",
|
||||
sol::property(&ExtractionWay::GetTurnLanesForward, &ExtractionWay::SetTurnLanesForward),
|
||||
"turn_lanes_backward",
|
||||
|
@ -37,7 +37,7 @@ StringView NameTable::GetNameForID(const NameID id) const
|
||||
if (id == INVALID_NAMEID)
|
||||
return {};
|
||||
|
||||
return m_name_table.at(id);
|
||||
return m_name_table.at(id + 0);
|
||||
}
|
||||
|
||||
StringView NameTable::GetDestinationsForID(const NameID id) const
|
||||
@ -48,6 +48,14 @@ StringView NameTable::GetDestinationsForID(const NameID id) const
|
||||
return m_name_table.at(id + 1);
|
||||
}
|
||||
|
||||
StringView NameTable::GetExitsForID(const NameID id) const
|
||||
{
|
||||
if (id == INVALID_NAMEID)
|
||||
return {};
|
||||
|
||||
return m_name_table.at(id + 4);
|
||||
}
|
||||
|
||||
StringView NameTable::GetRefForID(const NameID id) const
|
||||
{
|
||||
if (id == INVALID_NAMEID)
|
||||
@ -55,14 +63,14 @@ StringView NameTable::GetRefForID(const NameID id) const
|
||||
|
||||
// Way string data is stored in blocks based on `id` as follows:
|
||||
//
|
||||
// | name | destination | pronunciation | ref |
|
||||
// | name | destination | pronunciation | ref | exits
|
||||
// ^ ^
|
||||
// [range)
|
||||
// ^ id + 3
|
||||
//
|
||||
// `id + offset` gives us the range of chars.
|
||||
//
|
||||
// Offset 0 is name, 1 is destination, 2 is pronunciation, 3 is ref.
|
||||
// Offset 0 is name, 1 is destination, 2 is pronunciation, 3 is ref, 4 is exits
|
||||
// See datafacades and extractor callbacks for details.
|
||||
const constexpr auto OFFSET_REF = 3u;
|
||||
return m_name_table.at(id + OFFSET_REF);
|
||||
@ -75,14 +83,14 @@ StringView NameTable::GetPronunciationForID(const NameID id) const
|
||||
|
||||
// Way string data is stored in blocks based on `id` as follows:
|
||||
//
|
||||
// | name | destination | pronunciation | ref |
|
||||
// | name | destination | pronunciation | ref | exits
|
||||
// ^ ^
|
||||
// [range)
|
||||
// ^ id + 2
|
||||
//
|
||||
// `id + offset` gives us the range of chars.
|
||||
//
|
||||
// Offset 0 is name, 1 is destination, 2 is pronunciation, 3 is ref.
|
||||
// Offset 0 is name, 1 is destination, 2 is pronunciation, 3 is ref, 4 is exits
|
||||
// See datafacades and extractor callbacks for details.
|
||||
const constexpr auto OFFSET_PRONUNCIATION = 2u;
|
||||
return m_name_table.at(id + OFFSET_PRONUNCIATION);
|
||||
|
@ -350,6 +350,11 @@
|
||||
"object_types": [ "way" ],
|
||||
"description": "Destination and direction of road for oneways for navigation instructions, supplements name."
|
||||
},
|
||||
{
|
||||
"key": "junction:ref",
|
||||
"object_types": [ "way" ],
|
||||
"description": "Exit number or exit name of road for navigation instructions. Not to be confused with destination."
|
||||
},
|
||||
{
|
||||
"key": "junction",
|
||||
"object_types": [ "way" ],
|
||||
|
@ -201,6 +201,7 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
|
||||
StringView GetRefForID(const NameID) const override final { return {}; }
|
||||
StringView GetPronunciationForID(const NameID) const override final { return {}; }
|
||||
StringView GetDestinationsForID(const NameID) const override final { return {}; }
|
||||
StringView GetExitsForID(const NameID) const override final { return {}; }
|
||||
|
||||
std::string GetTimestamp() const override { return ""; }
|
||||
bool GetContinueStraightDefault() const override { return true; }
|
||||
|
@ -45,12 +45,17 @@ std::string PrapareNameTableData(std::vector<std::string> &data, bool fill_all)
|
||||
tmp = s + "_ref";
|
||||
name_offsets.push_back(name_char_data.size());
|
||||
std::copy(tmp.begin(), tmp.end(), std::back_inserter(name_char_data));
|
||||
|
||||
tmp = s + "_ext";
|
||||
name_offsets.push_back(name_char_data.size());
|
||||
std::copy(tmp.begin(), tmp.end(), std::back_inserter(name_char_data));
|
||||
}
|
||||
else
|
||||
{
|
||||
name_offsets.push_back(name_char_data.size());
|
||||
name_offsets.push_back(name_char_data.size());
|
||||
name_offsets.push_back(name_char_data.size());
|
||||
name_offsets.push_back(name_char_data.size());
|
||||
}
|
||||
}
|
||||
name_offsets.push_back(name_char_data.size());
|
||||
@ -89,6 +94,7 @@ BOOST_AUTO_TEST_CASE(check_name_table_fill)
|
||||
BOOST_CHECK_EQUAL(name_table.GetRefForID(id), expected_names[index] + "_ref");
|
||||
BOOST_CHECK_EQUAL(name_table.GetDestinationsForID(id), expected_names[index] + "_des");
|
||||
BOOST_CHECK_EQUAL(name_table.GetPronunciationForID(id), expected_names[index] + "_pro");
|
||||
BOOST_CHECK_EQUAL(name_table.GetExitsForID(id), expected_names[index] + "_ext");
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,6 +118,7 @@ BOOST_AUTO_TEST_CASE(check_name_table_nofill)
|
||||
BOOST_CHECK(name_table.GetRefForID(id).empty());
|
||||
BOOST_CHECK(name_table.GetDestinationsForID(id).empty());
|
||||
BOOST_CHECK(name_table.GetPronunciationForID(id).empty());
|
||||
BOOST_CHECK(name_table.GetExitsForID(id).empty());
|
||||
}
|
||||
// CALLGRIND_STOP_INSTRUMENTATION;
|
||||
}
|
||||
@ -123,6 +130,7 @@ BOOST_AUTO_TEST_CASE(check_invalid_ids)
|
||||
BOOST_CHECK_EQUAL(name_table.GetRefForID(INVALID_NAMEID), "");
|
||||
BOOST_CHECK_EQUAL(name_table.GetDestinationsForID(INVALID_NAMEID), "");
|
||||
BOOST_CHECK_EQUAL(name_table.GetPronunciationForID(INVALID_NAMEID), "");
|
||||
BOOST_CHECK_EQUAL(name_table.GetExitsForID(INVALID_NAMEID), "");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
Loading…
Reference in New Issue
Block a user