void CompressedEdgeContainer::AddUncompressedEdge(const EdgeID edge_id, const NodeID target_node_id, const SegmentWeight weight, const SegmentDuration duration) { // remove super-trivial geometries BOOST_ASSERT(SPECIAL_EDGEID != edge_id); BOOST_ASSERT(SPECIAL_NODEID != target_node_id); BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight); // Add via node id. List is created if it does not exist if (!HasEntryForID(edge_id)) { // create a new entry in the map if (0 == m_free_list.size()) { // make sure there is a place to put the entries IncreaseFreeList(); } BOOST_ASSERT(!m_free_list.empty()); m_edge_id_to_list_index_map[edge_id] = m_free_list.back(); m_free_list.pop_back(); } // find bucket index const auto iter = m_edge_id_to_list_index_map.find(edge_id); BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end()); const unsigned edge_bucket_id = iter->second; BOOST_ASSERT(edge_bucket_id == GetPositionForID(edge_id)); BOOST_ASSERT(edge_bucket_id < m_compressed_oneway_geometries.size()); std::vector<OnewayCompressedEdge> &edge_bucket_list = m_compressed_oneway_geometries[edge_bucket_id]; // note we don't save the start coordinate: it is implicitly given by edge_id // weight is the distance to the (currently) last coordinate in the bucket // Don't re-add this if it's already in there. if (edge_bucket_list.empty()) { edge_bucket_list.emplace_back( OnewayCompressedEdge{target_node_id, ClipWeight(weight), ClipDuration(duration)}); } }
void GeometryCompressor::CompressEdge(const EdgeID edge_id_1, const EdgeID edge_id_2, const NodeID via_node_id, const NodeID target_node_id, const EdgeWeight weight1, const EdgeWeight weight2) { // remove super-trivial geometries BOOST_ASSERT(SPECIAL_EDGEID != edge_id_1); BOOST_ASSERT(SPECIAL_EDGEID != edge_id_2); BOOST_ASSERT(SPECIAL_NODEID != via_node_id); BOOST_ASSERT(SPECIAL_NODEID != target_node_id); BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight1); BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight2); // append list of removed edge_id plus via node to surviving edge id: // <surv_1, .. , surv_n, via_node_id, rem_1, .. rem_n // // General scheme: // 1. append via node id to list of edge_id_1 // 2. find list for edge_id_2, if yes add all elements and delete it // Add via node id. List is created if it does not exist if (!HasEntryForID(edge_id_1)) { // create a new entry in the map if (0 == m_free_list.size()) { // make sure there is a place to put the entries IncreaseFreeList(); } BOOST_ASSERT(!m_free_list.empty()); m_edge_id_to_list_index_map[edge_id_1] = m_free_list.back(); m_free_list.pop_back(); } // find bucket index const auto iter = m_edge_id_to_list_index_map.find(edge_id_1); BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end()); const unsigned edge_bucket_id1 = iter->second; BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1)); BOOST_ASSERT(edge_bucket_id1 < m_compressed_geometries.size()); std::vector<CompressedNode> &edge_bucket_list1 = m_compressed_geometries[edge_bucket_id1]; if (edge_bucket_list1.empty()) { edge_bucket_list1.emplace_back(via_node_id, weight1); } BOOST_ASSERT(0 < edge_bucket_list1.size()); BOOST_ASSERT(!edge_bucket_list1.empty()); if (HasEntryForID(edge_id_2)) { // second edge is not atomic anymore const unsigned list_to_remove_index = GetPositionForID(edge_id_2); BOOST_ASSERT(list_to_remove_index < m_compressed_geometries.size()); std::vector<CompressedNode> &edge_bucket_list2 = m_compressed_geometries[list_to_remove_index]; // found an existing list, append it to the list of edge_id_1 edge_bucket_list1.insert( edge_bucket_list1.end(), edge_bucket_list2.begin(), edge_bucket_list2.end()); // remove the list of edge_id_2 m_edge_id_to_list_index_map.erase(edge_id_2); BOOST_ASSERT(m_edge_id_to_list_index_map.end() == m_edge_id_to_list_index_map.find(edge_id_2)); edge_bucket_list2.clear(); BOOST_ASSERT(0 == edge_bucket_list2.size()); m_free_list.emplace_back(list_to_remove_index); BOOST_ASSERT(list_to_remove_index == m_free_list.back()); } else { // we are certain that the second edge is atomic. edge_bucket_list1.emplace_back(target_node_id, weight2); } }
// Adds info for a compressed edge to the container. edge_id_2 // has been removed from the graph, so we have to save These edges/nodes // have already been trimmed from the graph, this function just stores // the original data for unpacking later. // // edge_id_1 edge_id_2 // ----------> via_node_id -----------> target_node_id // weight_1 weight_2 // duration_1 duration_2 void CompressedEdgeContainer::CompressEdge( const EdgeID edge_id_1, const EdgeID edge_id_2, const NodeID via_node_id, const NodeID target_node_id, const EdgeWeight weight1, const EdgeWeight weight2, const EdgeDuration duration1, const EdgeDuration duration2, const boost::optional<EdgeWeight> node_weight_penalty, const boost::optional<EdgeDuration> node_duration_penalty) { // remove super-trivial geometries BOOST_ASSERT(SPECIAL_EDGEID != edge_id_1); BOOST_ASSERT(SPECIAL_EDGEID != edge_id_2); BOOST_ASSERT(SPECIAL_NODEID != via_node_id); BOOST_ASSERT(SPECIAL_NODEID != target_node_id); BOOST_ASSERT(INVALID_SEGMENT_WEIGHT != weight1); BOOST_ASSERT(INVALID_SEGMENT_WEIGHT != weight2); // append list of removed edge_id plus via node to surviving edge id: // <surv_1, .. , surv_n, via_node_id, rem_1, .. rem_n // // General scheme: // 1. append via node id to list of edge_id_1 // 2. find list for edge_id_2, if yes add all elements and delete it // Add via node id. List is created if it does not exist if (!HasEntryForID(edge_id_1)) { // create a new entry in the map if (0 == m_free_list.size()) { // make sure there is a place to put the entries IncreaseFreeList(); } BOOST_ASSERT(!m_free_list.empty()); m_edge_id_to_list_index_map[edge_id_1] = m_free_list.back(); m_free_list.pop_back(); } // find bucket index const auto iter = m_edge_id_to_list_index_map.find(edge_id_1); BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end()); const unsigned edge_bucket_id1 = iter->second; BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1)); BOOST_ASSERT(edge_bucket_id1 < m_compressed_oneway_geometries.size()); std::vector<OnewayCompressedEdge> &edge_bucket_list1 = m_compressed_oneway_geometries[edge_bucket_id1]; bool was_empty = edge_bucket_list1.empty(); // note we don't save the start coordinate: it is implicitly given by edge 1 // weight1 is the distance to the (currently) last coordinate in the bucket if (was_empty) { edge_bucket_list1.emplace_back( OnewayCompressedEdge{via_node_id, ClipWeight(weight1), ClipDuration(duration1)}); } BOOST_ASSERT(0 < edge_bucket_list1.size()); BOOST_ASSERT(!edge_bucket_list1.empty()); // if the via-node offers a penalty, we add the weight of the penalty as an artificial // segment that references SPECIAL_NODEID if (node_weight_penalty && node_duration_penalty) { edge_bucket_list1.emplace_back(OnewayCompressedEdge{ via_node_id, ClipWeight(*node_weight_penalty), ClipDuration(*node_duration_penalty)}); } if (HasEntryForID(edge_id_2)) { // second edge is not atomic anymore const unsigned list_to_remove_index = GetPositionForID(edge_id_2); BOOST_ASSERT(list_to_remove_index < m_compressed_oneway_geometries.size()); std::vector<OnewayCompressedEdge> &edge_bucket_list2 = m_compressed_oneway_geometries[list_to_remove_index]; // found an existing list, append it to the list of edge_id_1 edge_bucket_list1.insert( edge_bucket_list1.end(), edge_bucket_list2.begin(), edge_bucket_list2.end()); // remove the list of edge_id_2 m_edge_id_to_list_index_map.erase(edge_id_2); BOOST_ASSERT(m_edge_id_to_list_index_map.end() == m_edge_id_to_list_index_map.find(edge_id_2)); edge_bucket_list2.clear(); BOOST_ASSERT(0 == edge_bucket_list2.size()); m_free_list.emplace_back(list_to_remove_index); BOOST_ASSERT(list_to_remove_index == m_free_list.back()); } else { // we are certain that the second edge is atomic. edge_bucket_list1.emplace_back( OnewayCompressedEdge{target_node_id, ClipWeight(weight2), ClipDuration(duration2)}); } }