Fixes for segregated length threshold.

This commit is contained in:
vng 2017-10-25 13:40:24 +00:00 committed by Michael Krasnyk
parent 76f793533a
commit 9eae1de9bc

View File

@ -846,13 +846,18 @@ struct EdgeInfo
ClassData road_class; ClassData road_class;
guidance::RoadPriorityClass::Enum road_priority_class;
struct LessName struct LessName
{ {
bool operator()(EdgeInfo const &e1, EdgeInfo const &e2) const { return e1.name < e2.name; } bool operator()(EdgeInfo const &e1, EdgeInfo const &e2) const { return e1.name < e2.name; }
}; };
}; };
bool IsSegregated(std::vector<EdgeInfo> v1, std::vector<EdgeInfo> v2, EdgeInfo const &current) bool IsSegregated(std::vector<EdgeInfo> v1,
std::vector<EdgeInfo> v2,
EdgeInfo const &current,
double edgeLength)
{ {
if (v1.size() < 2 || v2.size() < 2) if (v1.size() < 2 || v2.size() < 2)
return false; return false;
@ -881,6 +886,7 @@ bool IsSegregated(std::vector<EdgeInfo> v1, std::vector<EdgeInfo> v2, EdgeInfo c
return false; return false;
} }
/*
std::vector<EdgeInfo> intersect; std::vector<EdgeInfo> intersect;
std::set_intersection(v1.begin(), std::set_intersection(v1.begin(),
v1.end(), v1.end(),
@ -895,8 +901,8 @@ bool IsSegregated(std::vector<EdgeInfo> v1, std::vector<EdgeInfo> v2, EdgeInfo c
intersect.end()); intersect.end());
return intersect.size() >= 2; return intersect.size() >= 2;
*/
/*
// set_intersection like routine to count equal name pairs, std function is // set_intersection like routine to count equal name pairs, std function is
// not acceptable because of duplicates {a, a, b} ∩ {a, a, c} == {a, a}. // not acceptable because of duplicates {a, a, b} ∩ {a, a, c} == {a, a}.
std::vector<std::pair<EdgeInfo const *, EdgeInfo const *>> commons; std::vector<std::pair<EdgeInfo const *, EdgeInfo const *>> commons;
@ -906,22 +912,58 @@ bool IsSegregated(std::vector<EdgeInfo> v1, std::vector<EdgeInfo> v2, EdgeInfo c
while (i1 != v1.end() && i2 != v2.end()) while (i1 != v1.end() && i2 != v2.end())
{ {
if (i1->name_id == i2->name_id) if (i1->name == i2->name)
{ {
if (i1->name_id != EMPTY_NAMEID) if (!i1->name.empty())
commons.push_back(std::make_pair(&(*i1), &(*i2))); commons.push_back(std::make_pair(&(*i1), &(*i2)));
++i1; ++i1;
++i2; ++i2;
} }
else if (i1->name_id < i2->name_id) else if (i1->name < i2->name)
++i1; ++i1;
else else
++i2; ++i2;
} }
return (commons.size() >= 2); if (commons.size() < 2)
*/ return false;
auto const check_equal_class = [](std::pair<EdgeInfo const *, EdgeInfo const *> const &e) {
// Or (e.first->road_class & e.second->road_class != 0)
return e.first->road_class == e.second->road_class;
};
size_t equal_class_count = 0;
for (auto const &e : commons)
if (check_equal_class(e))
++equal_class_count;
if (equal_class_count < 2)
return false;
auto const get_length_threshold = [](EdgeInfo const *e) {
switch (e->road_priority_class)
{
case guidance::RoadPriorityClass::MOTORWAY:
case guidance::RoadPriorityClass::TRUNK:
return 15.0;
case guidance::RoadPriorityClass::PRIMARY:
return 10.0;
case guidance::RoadPriorityClass::SECONDARY:
case guidance::RoadPriorityClass::TERTIARY:
return 5.0;
default:
return 2.5;
}
};
double threshold = std::numeric_limits<double>::max();
for (auto const &e : commons)
threshold =
std::min(threshold, get_length_threshold(e.first) + get_length_threshold(e.second));
return edgeLength <= threshold;
/// @todo Process standalone U-turns. /// @todo Process standalone U-turns.
/* /*
@ -945,30 +987,32 @@ size_t Extractor::FindSegregatedNodes(NodeBasedGraphFactory &factory)
auto &graph = factory.GetGraph(); auto &graph = factory.GetGraph();
auto const &annotation = factory.GetAnnotationData(); auto const &annotation = factory.GetAnnotationData();
auto const &coordinates = factory.GetCoordinates();
auto const &edges = factory.GetCompressedEdges();
auto const get_edge_name = [&](auto const &data) { guidance::CoordinateExtractor coordExtractor(
/// @todo Make string normalization/lowercase/trim for comparison ... graph, factory.GetCompressedEdges(), factory.GetCoordinates());
auto const id = annotation[data.annotation_data].name_id; auto const get_edge_length = [&](NodeID from_node, EdgeID edgeID, NodeID to_node) {
BOOST_ASSERT(id != INVALID_NAMEID); auto const geom = coordExtractor.GetCoordinatesAlongRoad(from_node, edgeID, false, to_node);
return names.GetNameForID(id);
};
auto const get_edge_length = [&](EdgeID id) {
auto const geom = edges.GetBucketReference(id);
double length = 0.0; double length = 0.0;
for (size_t i = 1; i < geom.size(); ++i) for (size_t i = 1; i < geom.size(); ++i)
{ {
length += osrm::util::coordinate_calculation::haversineDistance( length += osrm::util::coordinate_calculation::haversineDistance(geom[i - 1], geom[i]);
coordinates[geom[i - 1].node_id], coordinates[geom[i].node_id]);
} }
return length; return length;
}; };
auto const get_edge_classes = [&](auto const &data) { auto const get_edge_info = [&](NodeID node, auto const &edgeData) -> EdgeInfo {
return annotation[data.annotation_data].classes; /// @todo Make string normalization/lowercase/trim for comparison ...
auto const id = annotation[edgeData.annotation_data].name_id;
BOOST_ASSERT(id != INVALID_NAMEID);
auto const name = names.GetNameForID(id);
return {node,
name,
edgeData.reversed ? 1 : 0,
annotation[edgeData.annotation_data].classes,
edgeData.flags.road_classification.GetClass()};
}; };
auto const collect_edge_info_fn = [&](auto const &edges1, NodeID node2) { auto const collect_edge_info_fn = [&](auto const &edges1, NodeID node2) {
@ -980,9 +1024,7 @@ size_t Extractor::FindSegregatedNodes(NodeBasedGraphFactory &factory)
if (target == node2) if (target == node2)
continue; continue;
auto const &data = graph.GetEdgeData(e); info.push_back(get_edge_info(target, graph.GetEdgeData(e)));
info.push_back(
{target, get_edge_name(data), data.reversed ? 1 : 0, get_edge_classes(data)});
} }
if (info.empty()) if (info.empty())
@ -1017,11 +1059,16 @@ size_t Extractor::FindSegregatedNodes(NodeBasedGraphFactory &factory)
return info; return info;
}; };
auto const isSegregatedFn = [&]( auto const isSegregatedFn = [&](auto const &edgeData,
auto const &edgeData, auto const &edges1, NodeID node1, auto const &edges2, NodeID node2) { auto const &edges1,
NodeID node1,
auto const &edges2,
NodeID node2,
double edgeLength) {
return IsSegregated(collect_edge_info_fn(edges1, node2), return IsSegregated(collect_edge_info_fn(edges1, node2),
collect_edge_info_fn(edges2, node1), collect_edge_info_fn(edges2, node1),
{node1, get_edge_name(edgeData), 0, get_edge_classes(edgeData)}); get_edge_info(node1, edgeData),
edgeLength);
}; };
std::unordered_set<EdgeID> processed; std::unordered_set<EdgeID> processed;
@ -1038,13 +1085,10 @@ size_t Extractor::FindSegregatedNodes(NodeBasedGraphFactory &factory)
continue; continue;
NodeID const targetID = graph.GetTarget(edgeID); NodeID const targetID = graph.GetTarget(edgeID);
if (get_edge_length(edgeID) > 30.0)
continue;
auto const targetEdges = graph.GetAdjacentEdgeRange(targetID); auto const targetEdges = graph.GetAdjacentEdgeRange(targetID);
if (isSegregatedFn(edgeData, sourceEdges, sourceID, targetEdges, targetID)) double const length = get_edge_length(sourceID, edgeID, targetID);
if (isSegregatedFn(edgeData, sourceEdges, sourceID, targetEdges, targetID, length))
{ {
++segregated_count; ++segregated_count;
edgeData.segregated = true; edgeData.segregated = true;