Add destinations API feature
This commit is contained in:
parent
bb0c2754d3
commit
6edc565c01
10
CHANGELOG.md
10
CHANGELOG.md
@ -6,11 +6,15 @@
|
||||
- BREAKING: modifies the file format with new internal identifiers
|
||||
|
||||
- API:
|
||||
- paramater `annotate` was renamed to `annotations`.
|
||||
- `annotation` as accidentally placed in `Route` instead of `RouteLeg`
|
||||
- paramater `annotate` was renamed to `annotations`.
|
||||
- `annotation` as accidentally placed in `Route` instead of `RouteLeg`
|
||||
- Support for destination signs. New member `destinations` in `RouteStep`, based on `destination` and `destination:ref`.
|
||||
|
||||
- Profile changes:
|
||||
- `result.destinations` allows you to set a way's destinations
|
||||
|
||||
- Infrastructure
|
||||
- BREAKING: Changed the on-disk encoding of the StaticRTree to reduce ramIndex file size. This breaks the **data format**
|
||||
- BREAKING: Changed the on-disk encoding of the StaticRTree to reduce ramIndex file size. This breaks the **data format**
|
||||
|
||||
- Bugfixes
|
||||
- fixed broken summaries for very short routes
|
||||
|
@ -437,6 +437,7 @@ step.
|
||||
|
||||
- `name`: The name of the way along which travel proceeds.
|
||||
- `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.
|
||||
- `maneuver`: A `StepManeuver` object representing the maneuver.
|
||||
- `intersections`: A list of `Intersections` that are passed along the segment, the very first belonging to the StepManeuver
|
||||
|
@ -29,13 +29,13 @@ Feature: Destination Signs
|
||||
| qr | QR | | | A1;A2 | yes | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | # |
|
||||
| a | b | AB (E1),AB (E1) | |
|
||||
| c | d | CD (Berlin),CD (Berlin) | |
|
||||
| e | f | EF (A1: Berlin),EF (A1: Berlin) | |
|
||||
| g | h | , | |
|
||||
| i | j | , | |
|
||||
| k | l | KL (E1),KL (E1) | |
|
||||
| m | n | MN (A1, A2: Berlin, Hamburg),MN (A1, A2: Berlin, Hamburg) | |
|
||||
| o | p | OP,OP | guard against mis-tagging |
|
||||
| q | r | QR (A1, A2),QR (A1, A2) | |
|
||||
| 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 | |
|
||||
|
@ -143,6 +143,10 @@ module.exports = function () {
|
||||
return this.extractInstructionList(instructions, s => s.pronunciation || '');
|
||||
};
|
||||
|
||||
this.destinationsList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, s => s.destinations || '');
|
||||
};
|
||||
|
||||
this.bearingList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, s => s.maneuver.bearing_before + '->' + s.maneuver.bearing_after);
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ module.exports = function () {
|
||||
var afterRequest = (err, res, body) => {
|
||||
if (err) return cb(err);
|
||||
if (body && body.length) {
|
||||
let pronunciations, instructions, bearings, turns, modes, times, distances, summary, intersections;
|
||||
let destinations, pronunciations, instructions, bearings, turns, modes, times, distances, summary, intersections;
|
||||
|
||||
let json = JSON.parse(body);
|
||||
|
||||
@ -42,6 +42,7 @@ module.exports = function () {
|
||||
if (hasRoute) {
|
||||
instructions = this.wayList(json.routes[0]);
|
||||
pronunciations = this.pronunciationList(json.routes[0]);
|
||||
destinations = this.destinationsList(json.routes[0]);
|
||||
bearings = this.bearingList(json.routes[0]);
|
||||
turns = this.turnList(json.routes[0]);
|
||||
intersections = this.intersectionList(json.routes[0]);
|
||||
@ -126,6 +127,7 @@ module.exports = function () {
|
||||
putValue('times', times);
|
||||
putValue('distances', distances);
|
||||
putValue('pronunciations', pronunciations);
|
||||
putValue('destinations', destinations);
|
||||
}
|
||||
|
||||
var ok = true;
|
||||
|
@ -147,6 +147,8 @@ class BaseDataFacade
|
||||
|
||||
virtual std::string GetPronunciationForID(const unsigned name_id) const = 0;
|
||||
|
||||
virtual std::string GetDestinationsForID(const unsigned name_id) const = 0;
|
||||
|
||||
virtual std::size_t GetCoreSize() const = 0;
|
||||
|
||||
virtual std::string GetTimestamp() const = 0;
|
||||
|
@ -593,9 +593,19 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
|
||||
std::string GetPronunciationForID(const unsigned name_id) const override final
|
||||
{
|
||||
// We store the pronounciation directly after the name of a street.
|
||||
// We store the pronounciation 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.
|
||||
// if we concatenate these. Order (see extractor_callbacks):
|
||||
// name (0), destination (1), pronunciation (2)
|
||||
return GetNameForID(name_id + 2);
|
||||
}
|
||||
|
||||
std::string GetDestinationsForID(const unsigned name_id) const override final
|
||||
{
|
||||
// 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)
|
||||
return GetNameForID(name_id + 1);
|
||||
}
|
||||
|
||||
|
@ -662,6 +662,19 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
|
||||
std::string GetPronunciationForID(const unsigned name_id) const override final
|
||||
{
|
||||
// We store the pronounciation 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)
|
||||
return GetNameForID(name_id + 2);
|
||||
}
|
||||
|
||||
std::string GetDestinationsForID(const unsigned name_id) const override final
|
||||
{
|
||||
// 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)
|
||||
return GetNameForID(name_id + 1);
|
||||
}
|
||||
|
||||
|
@ -99,11 +99,13 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
BOOST_ASSERT(segment_duration >= 0);
|
||||
const auto name = facade.GetNameForID(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(pronunciation),
|
||||
std::move(destinations),
|
||||
NO_ROTARY_NAME,
|
||||
segment_duration / 10.0,
|
||||
distance,
|
||||
@ -155,6 +157,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
facade.GetNameForID(step_name_id),
|
||||
facade.GetPronunciationForID(step_name_id),
|
||||
facade.GetDestinationsForID(step_name_id),
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
distance,
|
||||
@ -179,6 +182,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
steps.push_back(RouteStep{source_node.name_id,
|
||||
facade.GetNameForID(source_node.name_id),
|
||||
facade.GetPronunciationForID(source_node.name_id),
|
||||
facade.GetDestinationsForID(source_node.name_id),
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
leg_geometry.segment_distances[segment_index],
|
||||
@ -209,6 +213,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
steps.push_back(RouteStep{target_node.name_id,
|
||||
facade.GetNameForID(target_node.name_id),
|
||||
facade.GetPronunciationForID(target_node.name_id),
|
||||
facade.GetDestinationsForID(target_node.name_id),
|
||||
NO_ROTARY_NAME,
|
||||
ZERO_DURATION,
|
||||
ZERO_DISTANCE,
|
||||
|
@ -50,6 +50,7 @@ struct RouteStep
|
||||
unsigned name_id;
|
||||
std::string name;
|
||||
std::string pronunciation;
|
||||
std::string destinations;
|
||||
std::string rotary_name;
|
||||
double duration;
|
||||
double distance;
|
||||
@ -67,6 +68,7 @@ inline RouteStep getInvalidRouteStep()
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
0,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
|
@ -32,6 +32,7 @@ struct ExtractionWay
|
||||
is_access_restricted = false;
|
||||
name.clear();
|
||||
pronunciation.clear();
|
||||
destinations.clear();
|
||||
forward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
}
|
||||
@ -48,6 +49,7 @@ struct ExtractionWay
|
||||
double duration;
|
||||
std::string name;
|
||||
std::string pronunciation;
|
||||
std::string destinations;
|
||||
bool roundabout;
|
||||
bool is_access_restricted;
|
||||
bool is_startpoint;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
#include <boost/optional/optional_fwd.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
@ -34,7 +35,9 @@ class ExtractorCallbacks
|
||||
{
|
||||
private:
|
||||
// used to deduplicate street names and street destinations: actually maps to name ids
|
||||
std::unordered_map<std::string, unsigned> string_map;
|
||||
using MapKey = std::pair<std::string, std::string>;
|
||||
using MapVal = unsigned;
|
||||
std::unordered_map<MapKey, MapVal, boost::hash<MapKey>> string_map;
|
||||
ExtractionContainers &external_memory;
|
||||
|
||||
public:
|
||||
|
@ -407,6 +407,8 @@ function way_function (way, result)
|
||||
if has_destination and has_name and not has_ref then
|
||||
result.name = name .. " (" .. destination .. ")"
|
||||
end
|
||||
|
||||
result.destinations = destination
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -198,6 +198,8 @@ util::json::Object makeRouteStep(guidance::RouteStep step, util::json::Value geo
|
||||
route_step.values["name"] = std::move(step.name);
|
||||
if (!step.pronunciation.empty())
|
||||
route_step.values["pronunciation"] = std::move(step.pronunciation);
|
||||
if (!step.destinations.empty())
|
||||
route_step.values["destinations"] = std::move(step.destinations);
|
||||
if (!step.rotary_name.empty())
|
||||
route_step.values["rotary_name"] = std::move(step.rotary_name);
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace extractor
|
||||
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers)
|
||||
: external_memory(extraction_containers)
|
||||
{
|
||||
string_map[""] = 0;
|
||||
string_map[MapKey("", "")] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,25 +146,38 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
const constexpr auto MAX_STRING_LENGTH = 255u;
|
||||
|
||||
// Get the unique identifier for the street name
|
||||
const auto name_iterator = string_map.find(parsed_way.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));
|
||||
unsigned name_id = external_memory.name_lengths.size();
|
||||
if (string_map.end() == name_iterator)
|
||||
{
|
||||
auto name_length = std::min<unsigned>(MAX_STRING_LENGTH, parsed_way.name.size());
|
||||
auto destinations_length = std::min<unsigned>(MAX_STRING_LENGTH, parsed_way.destinations.size());
|
||||
auto pronunciation_length = std::min<unsigned>(MAX_STRING_LENGTH, parsed_way.pronunciation.size());
|
||||
|
||||
|
||||
external_memory.name_char_data.reserve(name_id + name_length + destinations_length + pronunciation_length);
|
||||
|
||||
external_memory.name_char_data.reserve(name_id + name_length);
|
||||
std::copy(parsed_way.name.c_str(),
|
||||
parsed_way.name.c_str() + name_length,
|
||||
std::back_inserter(external_memory.name_char_data));
|
||||
|
||||
external_memory.name_lengths.push_back(name_length);
|
||||
|
||||
auto pronunciation_length = std::min<unsigned>(255u, parsed_way.pronunciation.size());
|
||||
std::copy(parsed_way.pronunciation.c_str(), parsed_way.pronunciation.c_str() + pronunciation_length,
|
||||
std::copy(parsed_way.destinations.c_str(),
|
||||
parsed_way.destinations.c_str() + destinations_length,
|
||||
std::back_inserter(external_memory.name_char_data));
|
||||
|
||||
|
||||
std::copy(parsed_way.pronunciation.c_str(),
|
||||
parsed_way.pronunciation.c_str() + pronunciation_length,
|
||||
std::back_inserter(external_memory.name_char_data));
|
||||
|
||||
external_memory.name_lengths.push_back(name_length);
|
||||
external_memory.name_lengths.push_back(destinations_length);
|
||||
external_memory.name_lengths.push_back(pronunciation_length);
|
||||
|
||||
string_map.insert(std::make_pair(parsed_way.name, name_id));
|
||||
auto k = MapKey{parsed_way.name, parsed_way.destinations};
|
||||
auto v = MapVal{name_id};
|
||||
string_map.emplace(std::move(k), std::move(v));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -136,6 +136,7 @@ void ScriptingEnvironment::InitContext(ScriptingEnvironment::Context &context)
|
||||
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
|
||||
.def_readwrite("name", &ExtractionWay::name)
|
||||
.def_readwrite("pronunciation", &ExtractionWay::pronunciation)
|
||||
.def_readwrite("destinations", &ExtractionWay::destinations)
|
||||
.def_readwrite("roundabout", &ExtractionWay::roundabout)
|
||||
.def_readwrite("is_access_restricted", &ExtractionWay::is_access_restricted)
|
||||
.def_readwrite("is_startpoint", &ExtractionWay::is_startpoint)
|
||||
|
@ -172,6 +172,7 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
||||
unsigned GetNameIndexFromEdgeID(const unsigned /* id */) const override { return 0; }
|
||||
std::string GetNameForID(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; }
|
||||
std::string GetTimestamp() const override { return ""; }
|
||||
bool GetContinueStraightDefault() const override { return true; }
|
||||
|
Loading…
Reference in New Issue
Block a user