Split traces into subtraces
This commit is contained in:
+82
-65
@@ -62,9 +62,6 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
0.7977883096366508) // valid apriori probability
|
||||
{
|
||||
descriptor_table.emplace("json", 0);
|
||||
descriptor_table.emplace("gpx", 1);
|
||||
// descriptor_table.emplace("geojson", 2);
|
||||
//
|
||||
search_engine_ptr = std::make_shared<SearchEngine<DataFacadeT>>(facade);
|
||||
}
|
||||
|
||||
@@ -93,12 +90,13 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
return label_with_confidence;
|
||||
}
|
||||
|
||||
bool get_candiates(const std::vector<FixedPointCoordinate>& input_coords, double& trace_length, Matching::CandidateLists& candidates_lists)
|
||||
bool get_candiates(const std::vector<FixedPointCoordinate>& input_coords, std::vector<double>& sub_trace_lengths, Matching::CandidateLists& candidates_lists)
|
||||
{
|
||||
double last_distance = coordinate_calculation::great_circle_distance(
|
||||
input_coords[0],
|
||||
input_coords[1]);
|
||||
trace_length = 0;
|
||||
sub_trace_lengths.resize(input_coords.size());
|
||||
sub_trace_lengths[0] = 0;
|
||||
for (const auto current_coordinate : osrm::irange<std::size_t>(0, input_coords.size()))
|
||||
{
|
||||
bool allow_uturn = false;
|
||||
@@ -107,7 +105,7 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
last_distance = coordinate_calculation::great_circle_distance(
|
||||
input_coords[current_coordinate - 1],
|
||||
input_coords[current_coordinate]);
|
||||
trace_length += last_distance;
|
||||
sub_trace_lengths[current_coordinate] += sub_trace_lengths[current_coordinate-1] + last_distance;
|
||||
}
|
||||
|
||||
if (input_coords.size()-1 > current_coordinate && 0 < current_coordinate)
|
||||
@@ -171,10 +169,10 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
return 400;
|
||||
}
|
||||
|
||||
double trace_length;
|
||||
std::vector<double> sub_trace_lengths;
|
||||
Matching::CandidateLists candidates_lists;
|
||||
const auto& input_coords = route_parameters.coordinates;
|
||||
bool found_candidates = get_candiates(input_coords, trace_length, candidates_lists);
|
||||
bool found_candidates = get_candiates(input_coords, sub_trace_lengths, candidates_lists);
|
||||
if (!found_candidates)
|
||||
{
|
||||
return 400;
|
||||
@@ -182,72 +180,91 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
||||
|
||||
// call the actual map matching
|
||||
JSON::Object debug_info;
|
||||
float matched_length;
|
||||
std::vector<PhantomNode> matched_nodes;
|
||||
search_engine_ptr->map_matching(candidates_lists, input_coords, matched_nodes, matched_length, debug_info);
|
||||
Matching::SubMatchingList sub_matchings;
|
||||
search_engine_ptr->map_matching(candidates_lists, input_coords, sub_matchings, debug_info);
|
||||
|
||||
// classify result
|
||||
TraceClassification classification = classify(trace_length, matched_length, input_coords.size() - matched_nodes.size());
|
||||
if (classification.first == ClassifierT::ClassLabel::POSITIVE)
|
||||
{
|
||||
json_result.values["confidence"] = classification.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
json_result.values["confidence"] = 1-classification.second;
|
||||
}
|
||||
|
||||
// run shortest path routing to obtain geometry
|
||||
InternalRouteResult raw_route;
|
||||
PhantomNodes current_phantom_node_pair;
|
||||
for (unsigned i = 0; i < matched_nodes.size() - 1; ++i)
|
||||
{
|
||||
current_phantom_node_pair.source_phantom = matched_nodes[i];
|
||||
current_phantom_node_pair.target_phantom = matched_nodes[i + 1];
|
||||
raw_route.segment_end_coordinates.emplace_back(current_phantom_node_pair);
|
||||
}
|
||||
|
||||
if (2 > matched_nodes.size())
|
||||
if (1 > sub_matchings.size())
|
||||
{
|
||||
return 400;
|
||||
}
|
||||
|
||||
search_engine_ptr->shortest_path(
|
||||
raw_route.segment_end_coordinates,
|
||||
std::vector<bool>(raw_route.segment_end_coordinates.size(), true),
|
||||
raw_route);
|
||||
|
||||
DescriptorConfig descriptor_config;
|
||||
|
||||
auto iter = descriptor_table.find(route_parameters.output_format);
|
||||
unsigned descriptor_type = (iter != descriptor_table.end() ? iter->second : 0);
|
||||
|
||||
descriptor_config.zoom_level = route_parameters.zoom_level;
|
||||
descriptor_config.instructions = route_parameters.print_instructions;
|
||||
descriptor_config.geometry = route_parameters.geometry;
|
||||
descriptor_config.encode_geometry = route_parameters.compression;
|
||||
|
||||
std::shared_ptr<BaseDescriptor<DataFacadeT>> descriptor;
|
||||
switch (descriptor_type)
|
||||
JSON::Array traces;
|
||||
for (auto& sub : sub_matchings)
|
||||
{
|
||||
// case 0:
|
||||
// descriptor = std::make_shared<JSONDescriptor<DataFacadeT>>();
|
||||
// break;
|
||||
case 1:
|
||||
descriptor = std::make_shared<GPXDescriptor<DataFacadeT>>(facade);
|
||||
break;
|
||||
// case 2:
|
||||
// descriptor = std::make_shared<GEOJSONDescriptor<DataFacadeT>>();
|
||||
// break;
|
||||
default:
|
||||
descriptor = std::make_shared<JSONDescriptor<DataFacadeT>>(facade);
|
||||
break;
|
||||
// classify result
|
||||
double trace_length = sub_trace_lengths[sub.end_idx-1] - sub_trace_lengths[sub.begin_idx];
|
||||
TraceClassification classification = classify(trace_length,
|
||||
sub.length,
|
||||
(sub.end_idx - sub.begin_idx) - sub.nodes.size());
|
||||
if (classification.first == ClassifierT::ClassLabel::POSITIVE)
|
||||
{
|
||||
sub.confidence = classification.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
sub.confidence = 1-classification.second;
|
||||
}
|
||||
|
||||
// FIXME this is a pretty bad hack. Geometries should obtained directly
|
||||
// from map_matching.
|
||||
// run shortest path routing to obtain geometry
|
||||
InternalRouteResult raw_route;
|
||||
PhantomNodes current_phantom_node_pair;
|
||||
for (unsigned i = 0; i < sub.nodes.size() - 1; ++i)
|
||||
{
|
||||
current_phantom_node_pair.source_phantom = sub.nodes[i];
|
||||
current_phantom_node_pair.target_phantom = sub.nodes[i + 1];
|
||||
raw_route.segment_end_coordinates.emplace_back(current_phantom_node_pair);
|
||||
}
|
||||
search_engine_ptr->shortest_path(
|
||||
raw_route.segment_end_coordinates,
|
||||
std::vector<bool>(raw_route.segment_end_coordinates.size(), true),
|
||||
raw_route);
|
||||
|
||||
|
||||
DescriptorConfig descriptor_config;
|
||||
|
||||
auto iter = descriptor_table.find(route_parameters.output_format);
|
||||
unsigned descriptor_type = (iter != descriptor_table.end() ? iter->second : 0);
|
||||
|
||||
descriptor_config.zoom_level = route_parameters.zoom_level;
|
||||
descriptor_config.instructions = false;
|
||||
descriptor_config.geometry = route_parameters.geometry;
|
||||
descriptor_config.encode_geometry = route_parameters.compression;
|
||||
|
||||
std::shared_ptr<BaseDescriptor<DataFacadeT>> descriptor;
|
||||
switch (descriptor_type)
|
||||
{
|
||||
// case 0:
|
||||
// descriptor = std::make_shared<JSONDescriptor<DataFacadeT>>();
|
||||
// break;
|
||||
case 1:
|
||||
descriptor = std::make_shared<GPXDescriptor<DataFacadeT>>(facade);
|
||||
break;
|
||||
// case 2:
|
||||
// descriptor = std::make_shared<GEOJSONDescriptor<DataFacadeT>>();
|
||||
// break;
|
||||
default:
|
||||
descriptor = std::make_shared<JSONDescriptor<DataFacadeT>>(facade);
|
||||
break;
|
||||
}
|
||||
|
||||
JSON::Object temp_result;
|
||||
descriptor->SetConfig(descriptor_config);
|
||||
descriptor->Run(raw_route, temp_result);
|
||||
|
||||
JSON::Object subtrace;
|
||||
// via_route compability
|
||||
subtrace.values["route_geometry"] = temp_result.values["route_geometry"];
|
||||
subtrace.values["confidence"] = sub.confidence;
|
||||
subtrace.values["via_indicies"] = temp_result.values["via_indicies"];
|
||||
subtrace.values["via_points"] = temp_result.values["via_points"];
|
||||
|
||||
traces.values.push_back(subtrace);
|
||||
}
|
||||
|
||||
descriptor->SetConfig(descriptor_config);
|
||||
descriptor->Run(raw_route, json_result);
|
||||
|
||||
json_result.values["debug"] = debug_info;
|
||||
json_result.values["traces"] = traces;
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user