Fixes for segregated length threshold.
This commit is contained in:
parent
76f793533a
commit
9eae1de9bc
@ -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 ¤t)
|
bool IsSegregated(std::vector<EdgeInfo> v1,
|
||||||
|
std::vector<EdgeInfo> v2,
|
||||||
|
EdgeInfo const ¤t,
|
||||||
|
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user