diff --git a/Contractor/EdgeBasedGraphFactory.cpp b/Contractor/EdgeBasedGraphFactory.cpp index 9f6e64bee..cd87a4e69 100644 --- a/Contractor/EdgeBasedGraphFactory.cpp +++ b/Contractor/EdgeBasedGraphFactory.cpp @@ -21,52 +21,56 @@ #include "EdgeBasedGraphFactory.h" EdgeBasedGraphFactory::EdgeBasedGraphFactory( - int nodes, std::vector & inputEdges, + int number_of_nodes, + std::vector & input_edge_list, std::vector & barrier_node_list, std::vector & traffic_light_node_list, std::vector & input_restrictions_list, - std::vector & inputNodeInfoList, - SpeedProfileProperties speedProfile -) : speedProfile(speedProfile), + std::vector & m_node_info_list, + SpeedProfileProperties speed_profile +) : speed_profile(speed_profile), m_turn_restrictions_count(0), - inputNodeInfoList(inputNodeInfoList) + m_node_info_list(m_node_info_list) { BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) { - std::pair restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode); + std::pair restriction_source = + std::make_pair(restriction.fromNode, restriction.viaNode); unsigned index; - RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource); - if(restrIter == _restrictionMap.end()) { - index = _restrictionBucketVector.size(); - _restrictionBucketVector.resize(index+1); - _restrictionMap[restrictionSource] = index; + RestrictionMap::iterator restriction_iter = m_restriction_map.find(restriction_source); + if(restriction_iter == m_restriction_map.end()) { + index = m_restriction_bucket_list.size(); + m_restriction_bucket_list.resize(index+1); + m_restriction_map[restriction_source] = index; } else { - index = restrIter->second; + index = restriction_iter->second; //Map already contains an is_only_*-restriction - if(_restrictionBucketVector.at(index).begin()->second) + if(m_restriction_bucket_list.at(index).begin()->second) { continue; - else if(restriction.flags.isOnly){ + } else if(restriction.flags.isOnly) { //We are going to insert an is_only_*-restriction. There can be only one. - m_turn_restrictions_count -= _restrictionBucketVector.at(index).size(); - _restrictionBucketVector.at(index).clear(); + m_turn_restrictions_count -= m_restriction_bucket_list.at(index).size(); + m_restriction_bucket_list.at(index).clear(); } } ++m_turn_restrictions_count; - _restrictionBucketVector.at(index).push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly)); + m_restriction_bucket_list.at(index).push_back( + std::make_pair( restriction.toNode, restriction.flags.isOnly) + ); } - _barrierNodes.insert( + m_barrier_nodes.insert( barrier_node_list.begin(), barrier_node_list.end() ); - _trafficLights.insert( + m_traffic_lights.insert( traffic_light_node_list.begin(), traffic_light_node_list.end() ); - DeallocatingVector< _NodeBasedEdge > edges; - _NodeBasedEdge edge; - BOOST_FOREACH(const ImportEdge & import_edge, inputEdges) { + DeallocatingVector< NodeBasedEdge > edges_list; + NodeBasedEdge edge; + BOOST_FOREACH(const ImportEdge & import_edge, input_edge_list) { if(!import_edge.isForward()) { edge.source = import_edge.target(); edge.target = import_edge.source(); @@ -89,139 +93,189 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( edge.data.nameID = import_edge.name(); edge.data.type = import_edge.type(); edge.data.isAccessRestricted = import_edge.isAccessRestricted(); - edge.data.edgeBasedNodeID = edges.size(); + edge.data.edgeBasedNodeID = edges_list.size(); edge.data.contraFlow = import_edge.isContraFlow(); - edges.push_back( edge ); + edges_list.push_back( edge ); if( edge.data.backward ) { std::swap( edge.source, edge.target ); edge.data.forward = import_edge.isBackward(); edge.data.backward = import_edge.isForward(); - edge.data.edgeBasedNodeID = edges.size(); - edges.push_back( edge ); + edge.data.edgeBasedNodeID = edges_list.size(); + edges_list.push_back( edge ); } } - std::vector().swap(inputEdges); - std::sort( edges.begin(), edges.end() ); - _nodeBasedGraph = boost::make_shared<_NodeBasedDynamicGraph>( nodes, edges ); + std::vector().swap(input_edge_list); + std::sort( edges_list.begin(), edges_list.end() ); + m_node_based_graph = boost::make_shared( + number_of_nodes, edges_list + ); } -void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector< EdgeBasedEdge >& outputEdgeList ) { +void EdgeBasedGraphFactory::GetEdgeBasedEdges( + DeallocatingVector< EdgeBasedEdge >& output_edge_list +) { BOOST_ASSERT_MSG( - 0 == outputEdgeList.size(), + 0 == output_edge_list.size(), "Vector is not empty" ); - edgeBasedEdges.swap(outputEdgeList); + m_edge_based_edge_list.swap(output_edge_list); } void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector & nodes) { #ifndef NDEBUG - BOOST_FOREACH(const EdgeBasedNode & node, edgeBasedNodes){ + BOOST_FOREACH(const EdgeBasedNode & node, m_edge_based_node_list){ assert(node.lat1 != INT_MAX); assert(node.lon1 != INT_MAX); assert(node.lat2 != INT_MAX); assert(node.lon2 != INT_MAX); } #endif - nodes.swap(edgeBasedNodes); + nodes.swap(m_edge_based_node_list); } NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn( const NodeID u, const NodeID v ) const { - const std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); - RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); - if (restrIter != _restrictionMap.end()) { - const unsigned index = restrIter->second; - BOOST_FOREACH(const RestrictionSource & restrictionTarget, _restrictionBucketVector.at(index)) { - if(restrictionTarget.second) { - return restrictionTarget.first; + const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v); + RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source); + if (restriction_iter != m_restriction_map.end()) { + const unsigned index = restriction_iter->second; + BOOST_FOREACH( + const RestrictionSource & restriction_target, + m_restriction_bucket_list.at(index) + ) { + if(restriction_target.second) { + return restriction_target.first; } } } return UINT_MAX; } -bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const { +bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted( + const NodeID u, + const NodeID v, + const NodeID w +) const { //only add an edge if turn is not a U-turn except it is the end of dead-end street. - const std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); - RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); - if (restrIter != _restrictionMap.end()) { - const unsigned index = restrIter->second; - BOOST_FOREACH(const RestrictionTarget & restrictionTarget, _restrictionBucketVector.at(index)) { - if(w == restrictionTarget.first) + const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v); + RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source); + if (restriction_iter != m_restriction_map.end()) { + const unsigned index = restriction_iter->second; + BOOST_FOREACH( + const RestrictionTarget & restriction_target, + m_restriction_bucket_list.at(index) + ) { + if(w == restriction_target.first) { return true; + } } } return false; } void EdgeBasedGraphFactory::InsertEdgeBasedNode( - _NodeBasedDynamicGraph::EdgeIterator e1, - _NodeBasedDynamicGraph::NodeIterator u, - _NodeBasedDynamicGraph::NodeIterator v, + EdgeIterator e1, + NodeIterator u, + NodeIterator v, bool belongsToTinyComponent) { - _NodeBasedDynamicGraph::EdgeData & data = _nodeBasedGraph->GetEdgeData(e1); + EdgeData & data = m_node_based_graph->GetEdgeData(e1); EdgeBasedNode currentNode; currentNode.nameID = data.nameID; - currentNode.lat1 = inputNodeInfoList[u].lat; - currentNode.lon1 = inputNodeInfoList[u].lon; - currentNode.lat2 = inputNodeInfoList[v].lat; - currentNode.lon2 = inputNodeInfoList[v].lon; + currentNode.lat1 = m_node_info_list[u].lat; + currentNode.lon1 = m_node_info_list[u].lon; + currentNode.lat2 = m_node_info_list[v].lat; + currentNode.lon2 = m_node_info_list[v].lon; currentNode.belongsToTinyComponent = belongsToTinyComponent; currentNode.id = data.edgeBasedNodeID; currentNode.ignoreInGrid = data.ignoreInGrid; currentNode.weight = data.distance; - edgeBasedNodes.push_back(currentNode); + m_edge_based_node_list.push_back(currentNode); } -void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State *myLuaState) { - Percent p(_nodeBasedGraph->GetNumberOfNodes()); - int numberOfSkippedTurns(0); - int nodeBasedEdgeCounter(0); - unsigned numberOfOriginalEdges(0); - std::ofstream originalEdgeDataOutFile(originalEdgeDataFilename, std::ios::binary); - originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned)); +void EdgeBasedGraphFactory::Run( + const char * original_edge_data_filename, + lua_State *lua_state +) { + SimpleLogger().Write() << "Identifying components of the road network"; + Percent p(m_node_based_graph->GetNumberOfNodes()); + unsigned skipped_turns_counter = 0; + unsigned node_based_edge_counter = 0; + unsigned original_edges_counter = 0; - SimpleLogger().Write() << "Identifying small components"; + std::ofstream edge_data_file( + original_edge_data_filename, + std::ios::binary + ); + + //writes a dummy value that is updated later + edge_data_file.write( + (char*)&original_edges_counter, + sizeof(unsigned) + ); + + unsigned current_component = 0, current_component_size = 0; //Run a BFS on the undirected graph and identify small components - std::queue > bfsQueue; - std::vector componentsIndex(_nodeBasedGraph->GetNumberOfNodes(), UINT_MAX); - std::vector vectorOfComponentSizes; - unsigned currentComponent = 0, sizeOfCurrentComponent = 0; + std::queue > bfs_queue; + std::vector component_index_list( + m_node_based_graph->GetNumberOfNodes(), + UINT_MAX + ); + + std::vector component_size_list; //put unexplorered node with parent pointer into queue - for(NodeID node = 0, endNodes = _nodeBasedGraph->GetNumberOfNodes(); node < endNodes; ++node) { - if(UINT_MAX == componentsIndex[node]) { - bfsQueue.push(std::make_pair(node, node)); + for( + NodeID node = 0, + last_node = m_node_based_graph->GetNumberOfNodes(); + node < last_node; + ++node + ) { + if(UINT_MAX == component_index_list[node]) { + bfs_queue.push(std::make_pair(node, node)); //mark node as read - componentsIndex[node] = currentComponent; + component_index_list[node] = current_component; p.printIncrement(); - while(!bfsQueue.empty()) { + while(!bfs_queue.empty()) { //fetch element from BFS queue - std::pair currentQueueItem = bfsQueue.front(); - bfsQueue.pop(); - // SimpleLogger().Write() << "sizeof queue: " << bfsQueue.size() << ", sizeOfCurrentComponents: " << sizeOfCurrentComponent << ", settled nodes: " << settledNodes++ << ", max: " << endNodes; - const NodeID v = currentQueueItem.first; //current node - const NodeID u = currentQueueItem.second; //parent + std::pair current_queue_item = bfs_queue.front(); + bfs_queue.pop(); + // SimpleLogger().Write() << "sizeof queue: " << bfs_queue.size() << + // ", current_component_sizes: " << current_component_size << + //", settled nodes: " << settledNodes++ << ", max: " << endNodes; + const NodeID v = current_queue_item.first; //current node + const NodeID u = current_queue_item.second; //parent //increment size counter of current component - ++sizeOfCurrentComponent; - const bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end()); - if(!isBollardNode) { - const NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v); + ++current_component_size; + const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end()); + if(!is_barrier_node) { + const NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v); //relaxieren edge outgoing edge like below where edge-expanded graph - for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { - _NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); + for( + EdgeIterator e2 = m_node_based_graph->BeginEdges(v); + e2 < m_node_based_graph->EndEdges(v); + ++e2 + ) { + NodeIterator w = m_node_based_graph->GetTarget(e2); - if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn. + if( + to_node_of_only_restriction != UINT_MAX && + w != to_node_of_only_restriction + ) { + //We are at an only_-restriction but not at the right turn. continue; } - if( u != w ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street. - if (!CheckIfTurnIsRestricted(u, v, w) ) { //only add an edge if turn is not prohibited - //insert next (node, parent) only if w has not yet been explored - if(UINT_MAX == componentsIndex[w]) { + if( u != w ) { + //only add an edge if turn is not a U-turn except + //when it is at the end of a dead-end street. + if (!CheckIfTurnIsRestricted(u, v, w) ) { + //only add an edge if turn is not prohibited + if(UINT_MAX == component_index_list[w]) { + //insert next (node, parent) only if w has + //not yet been explored //mark node as read - componentsIndex[w] = currentComponent; - bfsQueue.push(std::make_pair(w,v)); + component_index_list[w] = current_component; + bfs_queue.push(std::make_pair(w,v)); p.printIncrement(); } } @@ -230,142 +284,206 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State } } //push size into vector - vectorOfComponentSizes.push_back(sizeOfCurrentComponent); + component_size_list.push_back(current_component_size); //reset counters; - sizeOfCurrentComponent = 0; - ++currentComponent; + current_component_size = 0; + ++current_component; } } - SimpleLogger().Write() << "identified: " << vectorOfComponentSizes.size() << " many components"; + SimpleLogger().Write() << + "identified: " << component_size_list.size() << " many components"; - p.reinit(_nodeBasedGraph->GetNumberOfNodes()); + p.reinit(m_node_based_graph->GetNumberOfNodes()); //loop over all edges and generate new set of nodes. - for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { - for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { - _NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); + for( + NodeIterator u = 0, + number_of_nodes = m_node_based_graph->GetNumberOfNodes(); + u < number_of_nodes; + ++u + ) { + for( + EdgeIterator e1 = m_node_based_graph->BeginEdges(u), + last_edge = m_node_based_graph->EndEdges(u); + e1 < last_edge; + ++e1 + ) { + NodeIterator v = m_node_based_graph->GetTarget(e1); - if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) { - assert(e1 != UINT_MAX); - assert(u != UINT_MAX); - assert(v != UINT_MAX); - //edges that end on bollard nodes may actually be in two distinct components - InsertEdgeBasedNode(e1, u, v, (std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 1000) ); + if(m_node_based_graph->GetEdgeData(e1).type != SHRT_MAX) { + BOOST_ASSERT_MSG(e1 != UINT_MAX, "edge id invalid"); + BOOST_ASSERT_MSG(u != UINT_MAX, "souce node invalid"); + BOOST_ASSERT_MSG(v != UINT_MAX, "target node invalid"); + //Note: edges that end on barrier nodes or on a turn restriction + //may actually be in two distinct components. We choose the smallest + const unsigned size_of_component = std::min( + component_size_list[component_index_list[u]], + component_size_list[component_index_list[v]] + ); + + InsertEdgeBasedNode( e1, u, v, size_of_component < 1000 ); } } } - std::vector().swap(vectorOfComponentSizes); - std::vector().swap(componentsIndex); - + std::vector().swap(component_size_list); + BOOST_ASSERT_MSG( + 0 == component_size_list.capacity(), + "component size vector not deallocated" + ); + std::vector().swap(component_index_list); + BOOST_ASSERT_MSG( + 0 == component_index_list.capacity(), + "component index vector not deallocated" + ); std::vector original_edge_data_vector; original_edge_data_vector.reserve(10000); //Loop over all turns and generate new set of edges. - //Three nested loop look super-linear, but we are dealing with a linear number of turns only. - for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { - for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { - ++nodeBasedEdgeCounter; - _NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); - bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end()); - //EdgeWeight heightPenalty = ComputeHeightPenalty(u, v); - NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v); - for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { - const _NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); - - if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn. - ++numberOfSkippedTurns; + //Three nested loop look super-linear, but we are dealing with a (kind of) + //linear number of turns only. + for( + NodeIterator u = 0, + last_node = m_node_based_graph->GetNumberOfNodes(); + u < last_node; + ++u + ) { + for( + EdgeIterator e1 = m_node_based_graph->BeginEdges(u), + last_edge_u = m_node_based_graph->EndEdges(u); + e1 < last_edge_u; + ++e1 + ) { + ++node_based_edge_counter; + NodeIterator v = m_node_based_graph->GetTarget(e1); + bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end()); + NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v); + for( + EdgeIterator e2 = m_node_based_graph->BeginEdges(v), + last_edge_v = m_node_based_graph->EndEdges(v); + e2 < last_edge_v; + ++e2 + ) { + const NodeIterator w = m_node_based_graph->GetTarget(e2); + if( + to_node_of_only_restriction != UINT_MAX && + w != to_node_of_only_restriction + ) { + //We are at an only_-restriction but not at the right turn. + ++skipped_turns_counter; continue; } - if(u == w && 1 != _nodeBasedGraph->GetOutDegree(v) ) { + if(u == w && 1 != m_node_based_graph->GetOutDegree(v) ) { continue; } - if( !isBollardNode ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street. - if (!CheckIfTurnIsRestricted(u, v, w) || (onlyToNode != UINT_MAX && w == onlyToNode)) { //only add an edge if turn is not prohibited - const _NodeBasedDynamicGraph::EdgeData edgeData1 = _nodeBasedGraph->GetEdgeData(e1); - const _NodeBasedDynamicGraph::EdgeData edgeData2 = _nodeBasedGraph->GetEdgeData(e2); - assert(edgeData1.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges()); - assert(edgeData2.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges()); + if( !is_barrier_node ) { + //only add an edge if turn is not a U-turn except when it is + //at the end of a dead-end street + if ( + !CheckIfTurnIsRestricted(u, v, w) || + (to_node_of_only_restriction != UINT_MAX && w == to_node_of_only_restriction) + ) { //only add an edge if turn is not prohibited + const EdgeData edge_data1 = m_node_based_graph->GetEdgeData(e1); + const EdgeData edge_data2 = m_node_based_graph->GetEdgeData(e2); + assert(edge_data1.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges()); + assert(edge_data2.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges()); - if(!edgeData1.forward || !edgeData2.forward) { + if(!edge_data1.forward || !edge_data2.forward) { continue; } - unsigned distance = edgeData1.distance; - if(_trafficLights.find(v) != _trafficLights.end()) { - distance += speedProfile.trafficSignalPenalty; + unsigned distance = edge_data1.distance; + if(m_traffic_lights.find(v) != m_traffic_lights.end()) { + distance += speed_profile.trafficSignalPenalty; } - unsigned penalty = GetTurnPenalty(u, v, w, myLuaState); + const unsigned penalty = + GetTurnPenalty(u, v, w, lua_state); TurnInstruction turnInstruction = AnalyzeTurn(u, v, w); - if(turnInstruction == TurnInstructions.UTurn) - distance += speedProfile.uTurnPenalty; -// if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) { -// distance += TurnInstructions.AccessRestrictionPenalty; -// turnInstruction |= TurnInstructions.AccessRestrictionFlag; -// } + if(turnInstruction == TurnInstructions.UTurn){ + distance += speed_profile.uTurnPenalty; + } distance += penalty; - //distance += heightPenalty; //distance += ComputeTurnPenalty(u, v, w); - assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID); - OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction); - original_edge_data_vector.push_back(oed); - ++numberOfOriginalEdges; + assert(edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID); + original_edge_data_vector.push_back( + OriginalEdgeData( + v, + edge_data2.nameID, + turnInstruction + ) + ); + ++original_edges_counter; if(original_edge_data_vector.size() > 100000) { - originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData)); + edge_data_file.write( + (char*)&(original_edge_data_vector[0]), + original_edge_data_vector.size()*sizeof(OriginalEdgeData) + ); original_edge_data_vector.clear(); } - EdgeBasedEdge newEdge(edgeData1.edgeBasedNodeID, edgeData2.edgeBasedNodeID, edgeBasedEdges.size(), distance, true, false ); - edgeBasedEdges.push_back(newEdge); + m_edge_based_edge_list.push_back( + EdgeBasedEdge( + edge_data1.edgeBasedNodeID, + edge_data2.edgeBasedNodeID, + m_edge_based_edge_list.size(), + distance, + true, + false + ) + ); } else { - ++numberOfSkippedTurns; + ++skipped_turns_counter; } } } } p.printIncrement(); } - originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData)); - originalEdgeDataOutFile.seekp(std::ios::beg); - originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned)); - originalEdgeDataOutFile.close(); + edge_data_file.write( + (char*)&(original_edge_data_vector[0]), + original_edge_data_vector.size()*sizeof(OriginalEdgeData) + ); + edge_data_file.seekp(std::ios::beg); + edge_data_file.write( + (char*)&original_edges_counter, + sizeof(unsigned) + ); + edge_data_file.close(); -// SimpleLogger().Write() <<"Sorting edge-based Nodes"; -// std::sort(edgeBasedNodes.begin(), edgeBasedNodes.end(); -// SimpleLogger().Write() <<"Removing duplicate nodes (if any)"; -// edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() ); -// SimpleLogger().Write() <<"Applying vector self-swap trick to free up memory"; -// SimpleLogger().Write() <<"size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity(); -// std::vector(edgeBasedNodes).swap(edgeBasedNodes); -// SimpleLogger().Write() <<"size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity(); - SimpleLogger().Write() <<"Node-based graph contains " << nodeBasedEdgeCounter << " edges"; - SimpleLogger().Write() <<"Edge-based graph contains " << edgeBasedEdges.size() << " edges"; -// SimpleLogger().Write() << "Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << 2*((double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter; - SimpleLogger().Write() <<"Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << numberOfTurnRestrictions << " restrictions."; - SimpleLogger().Write() <<"Generated " << edgeBasedNodes.size() << " edge based nodes"; + SimpleLogger().Write() << + "Generated " << m_edge_based_node_list.size() << " edge based nodes"; + SimpleLogger().Write() << + "Node-based graph contains " << node_based_edge_counter << " edges"; + SimpleLogger().Write() << + "Edge-expanded graph ..."; + SimpleLogger().Write() << + " contains " << m_edge_based_edge_list.size() << " edges"; + SimpleLogger().Write() << + " skips " << skipped_turns_counter << " turns, " + "defined by " << m_turn_restrictions_count << " restrictions"; } int EdgeBasedGraphFactory::GetTurnPenalty( const NodeID u, const NodeID v, const NodeID w, - lua_State *myLuaState + lua_State *lua_state ) const { - const double angle = GetAngleBetweenTwoEdges( - inputNodeInfoList[u], - inputNodeInfoList[v], - inputNodeInfoList[w] + const double angle = GetAngleBetweenThreeFixedPointCoordinates ( + m_node_info_list[u], + m_node_info_list[v], + m_node_info_list[w] ); - if( speedProfile.has_turn_penalty_function ) { + if( speed_profile.has_turn_penalty_function ) { try { //call lua profile to compute turn penalty return luabind::call_function( - myLuaState, + lua_state, "turn_function", 180.-angle ); @@ -381,17 +499,15 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn( const NodeID v, const NodeID w ) const { - const double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]); - if(u == w) { return TurnInstructions.UTurn; } - _NodeBasedDynamicGraph::EdgeIterator edge1 = _nodeBasedGraph->FindEdge(u, v); - _NodeBasedDynamicGraph::EdgeIterator edge2 = _nodeBasedGraph->FindEdge(v, w); + EdgeIterator edge1 = m_node_based_graph->FindEdge(u, v); + EdgeIterator edge2 = m_node_based_graph->FindEdge(v, w); - _NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1); - _NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2); + EdgeData & data1 = m_node_based_graph->GetEdgeData(edge1); + EdgeData & data2 = m_node_based_graph->GetEdgeData(edge2); if(!data1.contraFlow && data2.contraFlow) { return TurnInstructions.EnterAgainstAllowedDirection; @@ -403,7 +519,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn( //roundabouts need to be handled explicitely if(data1.roundabout && data2.roundabout) { //Is a turn possible? If yes, we stay on the roundabout! - if( 1 == (_nodeBasedGraph->EndEdges(v) - _nodeBasedGraph->BeginEdges(v)) ) { + if( 1 == m_node_based_graph->GetOutDegree(v) ) { //No turn possible. return TurnInstructions.NoTurn; } @@ -421,31 +537,28 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn( } } - //If street names stay the same and if we are certain that it is not a roundabout, we skip it. - if( (data1.nameID == data2.nameID) && (0 != data1.nameID)) { - return TurnInstructions.NoTurn; - } - if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) ) { - return TurnInstructions.NoTurn; + //If street names stay the same and if we are certain that it is not a + //a segment of a roundabout, we skip it. + if( data1.nameID == data2.nameID ) { + //TODO: Here we should also do a small graph exploration to check for + // more complex situations + if( 0 != data1.nameID ) { + return TurnInstructions.NoTurn; + } else if (m_node_based_graph->GetOutDegree(v) <= 2) { + return TurnInstructions.NoTurn; + } } + const double angle = GetAngleBetweenThreeFixedPointCoordinates ( + m_node_info_list[u], + m_node_info_list[v], + m_node_info_list[w] + ); + return TurnInstructions.GetTurnDirectionOfInstruction(angle); } unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const { - return _nodeBasedGraph->GetNumberOfEdges(); + return m_node_based_graph->GetNumberOfEdges(); } -/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/ -template -double EdgeBasedGraphFactory::GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const { - const double v1x = (A.lon - C.lon)/COORDINATE_PRECISION; - const double v1y = lat2y(A.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION); - const double v2x = (B.lon - C.lon)/COORDINATE_PRECISION; - const double v2y = lat2y(B.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION); - - double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI; - while(angle < 0) - angle += 360; - return angle; -} diff --git a/Contractor/EdgeBasedGraphFactory.h b/Contractor/EdgeBasedGraphFactory.h index 05b8462b3..5f4df157b 100644 --- a/Contractor/EdgeBasedGraphFactory.h +++ b/Contractor/EdgeBasedGraphFactory.h @@ -18,9 +18,7 @@ or see http://www.gnu.org/licenses/agpl.txt. */ -/* - * This class constructs the edge base representation of a graph from a given node based edge list - */ +// This class constructs the edge-expanded routing graph #ifndef EDGEBASEDGRAPHFACTORY_H_ #define EDGEBASEDGRAPHFACTORY_H_ @@ -31,15 +29,12 @@ #include "../Extractor/ExtractorStructs.h" #include "../DataStructures/HashTable.h" #include "../DataStructures/ImportEdge.h" -#include "../DataStructures/MercatorUtil.h" #include "../DataStructures/QueryEdge.h" #include "../DataStructures/Percent.h" #include "../DataStructures/TurnInstructions.h" #include "../Util/LuaUtil.h" #include "../Util/SimpleLogger.h" -#include - #include #include #include @@ -47,9 +42,8 @@ #include #include -#include - #include +#include #include #include @@ -67,6 +61,7 @@ public: weight(UINT_MAX >> 1), ignoreInGrid(false) { } + bool operator<(const EdgeBasedNode & other) const { return other.id < id; } @@ -100,33 +95,47 @@ public: }; struct SpeedProfileProperties{ - SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0), has_turn_penalty_function(false) {} + SpeedProfileProperties() : + trafficSignalPenalty(0), + uTurnPenalty(0), + has_turn_penalty_function(false) + { } + int trafficSignalPenalty; int uTurnPenalty; bool has_turn_penalty_function; - } speedProfile; + } speed_profile; explicit EdgeBasedGraphFactory( - int nodes, - std::vector & inputEdges, - std::vector & _bollardNodes, - std::vector & trafficLights, - std::vector & inputRestrictions, - std::vector & nI, - SpeedProfileProperties speedProfile + int number_of_nodes, + std::vector & input_edge_list, + std::vector & barrier_node_list, + std::vector & traffic_light_node_list, + std::vector & input_restrictions_list, + std::vector & m_node_info_list, + SpeedProfileProperties speed_profile ); void Run(const char * originalEdgeDataFilename, lua_State *myLuaState); void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges ); void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes); - void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData); - TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const; - int GetTurnPenalty(const NodeID u, const NodeID v, const NodeID w, lua_State *myLuaState) const; + void GetOriginalEdgeData( std::vector & originalEdgeData); + TurnInstruction AnalyzeTurn( + const NodeID u, + const NodeID v, + const NodeID w + ) const; + int GetTurnPenalty( + const NodeID u, + const NodeID v, + const NodeID w, + lua_State *myLuaState + ) const; unsigned GetNumberOfNodes() const; private: - struct _NodeBasedEdgeData { + struct NodeBasedEdgeData { int distance; unsigned edgeBasedNodeID; unsigned nameID; @@ -151,35 +160,44 @@ private: unsigned m_turn_restrictions_count; - typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph; - typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge; - std::vector inputNodeInfoList; - unsigned numberOfTurnRestrictions; - - boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph; - boost::unordered_set _barrierNodes; - boost::unordered_set _trafficLights; - - typedef std::pair RestrictionSource; - typedef std::pair RestrictionTarget; - typedef std::vector EmanatingRestrictionsVector; + typedef DynamicGraph NodeBasedDynamicGraph; + typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge; + typedef NodeBasedDynamicGraph::NodeIterator NodeIterator; + typedef NodeBasedDynamicGraph::EdgeIterator EdgeIterator; + typedef NodeBasedDynamicGraph::EdgeData EdgeData; + typedef std::pair RestrictionSource; + typedef std::pair RestrictionTarget; + typedef std::vector EmanatingRestrictionsVector; typedef boost::unordered_map RestrictionMap; - std::vector _restrictionBucketVector; - RestrictionMap _restrictionMap; - DeallocatingVector edgeBasedEdges; - std::vector edgeBasedNodes; + std::vector m_node_info_list; + std::vector m_restriction_bucket_list; + std::vector m_edge_based_node_list; + DeallocatingVector m_edge_based_edge_list; + + boost::shared_ptr m_node_based_graph; + boost::unordered_set m_barrier_nodes; + boost::unordered_set m_traffic_lights; + + RestrictionMap m_restriction_map; + + + NodeID CheckForEmanatingIsOnlyTurn( + const NodeID u, + const NodeID v + ) const; + + bool CheckIfTurnIsRestricted( + const NodeID u, + const NodeID v, + const NodeID w + ) const; - NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const; - bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const; void InsertEdgeBasedNode( - _NodeBasedDynamicGraph::EdgeIterator e1, - _NodeBasedDynamicGraph::NodeIterator u, - _NodeBasedDynamicGraph::NodeIterator v, + NodeBasedDynamicGraph::EdgeIterator e1, + NodeBasedDynamicGraph::NodeIterator u, + NodeBasedDynamicGraph::NodeIterator v, bool belongsToTinyComponent); - template - double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const; - }; #endif /* EDGEBASEDGRAPHFACTORY_H_ */ diff --git a/DataStructures/Coordinate.h b/DataStructures/Coordinate.h index a701f80db..bf0d3eaad 100644 --- a/DataStructures/Coordinate.h +++ b/DataStructures/Coordinate.h @@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef FIXED_POINT_COORDINATE_H_ #define FIXED_POINT_COORDINATE_H_ +#include "../DataStructures/MercatorUtil.h" #include "../Util/StringUtil.h" #include @@ -35,7 +36,7 @@ struct FixedPointCoordinate { int lat; int lon; FixedPointCoordinate () : lat(INT_MIN), lon(INT_MIN) {} - explicit FixedPointCoordinate (int t, int n) : lat(t) , lon(n) {} + explicit FixedPointCoordinate (int lat, int lon) : lat(lat) , lon(lon) {} void Reset() { lat = INT_MIN; @@ -141,4 +142,22 @@ static inline void convertInternalReversedCoordinateToString(const FixedPointCoo output += " "; } + +/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/ +template +static inline double GetAngleBetweenThreeFixedPointCoordinates ( + const CoordinateT & A, + const CoordinateT & C, + const CoordinateT & B +) { + const double v1x = (A.lon - C.lon)/COORDINATE_PRECISION; + const double v1y = lat2y(A.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION); + const double v2x = (B.lon - C.lon)/COORDINATE_PRECISION; + const double v2y = lat2y(B.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION); + + double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI; + while(angle < 0) + angle += 360; + return angle; +} #endif /* FIXED_POINT_COORDINATE_H_ */ diff --git a/DataStructures/QueryEdge.h b/DataStructures/QueryEdge.h index ef7c6b20b..1a7c39223 100644 --- a/DataStructures/QueryEdge.h +++ b/DataStructures/QueryEdge.h @@ -18,8 +18,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or see http://www.gnu.org/licenses/agpl.txt. */ - - #ifndef QUERYEDGE_H_ #define QUERYEDGE_H_