diff options
-rw-r--r-- | 3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.cpp | 77 | ||||
-rw-r--r-- | 3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.h | 26 | ||||
-rw-r--r-- | 3party/osrm/osrm-backend/Contractor/Prepare.cpp | 19 | ||||
-rw-r--r-- | 3party/osrm/osrm-backend/DataStructures/EdgeBasedNodeData.h | 123 | ||||
-rw-r--r-- | generator/routing_generator.cpp | 178 | ||||
-rw-r--r-- | generator/routing_generator.hpp | 2 | ||||
-rw-r--r-- | routing/osrm_data_facade_types.hpp | 119 | ||||
-rw-r--r-- | routing/routing.pro | 1 |
8 files changed, 426 insertions, 119 deletions
diff --git a/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.cpp b/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.cpp index 8b887ea6a2..2054283ec8 100644 --- a/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.cpp +++ b/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.cpp @@ -41,6 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. EdgeBasedGraphFactory::EdgeBasedGraphFactory( const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph, + const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph_origin, std::unique_ptr<RestrictionMap> restriction_map, std::vector<NodeID> &barrier_node_list, std::vector<NodeID> &traffic_light_node_list, @@ -49,6 +50,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( : speed_profile(speed_profile), m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()), m_node_info_list(m_node_info_list), m_node_based_graph(node_based_graph), + m_node_based_graph_origin(node_based_graph_origin), m_restriction_map(std::move(restriction_map)), max_id(0) { @@ -77,7 +79,7 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes) nodes.swap(m_edge_based_node_list); } -void EdgeBasedGraphFactory::GetEdgeBasedNodeData(std::vector<NodeData> &data) +void EdgeBasedGraphFactory::GetEdgeBasedNodeData(osrm::NodeDataVectorT &data) { data.swap(m_edge_based_node_data); } @@ -269,10 +271,6 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename, RenumberEdges(); TIMER_STOP(renumber); - TIMER_START(generate_node_data); - GenerateEdgeBasedNodeData(); - TIMER_STOP(generate_node_data); - TIMER_START(generate_nodes); GenerateEdgeExpandedNodes(); TIMER_STOP(generate_nodes); @@ -281,6 +279,11 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename, GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state); TIMER_STOP(generate_edges); + TIMER_START(generate_node_data); + GenerateEdgeBasedNodeData(); + TIMER_STOP(generate_node_data); + + m_geometry_compressor.SerializeInternalVector(geometry_filename); SimpleLogger().Write() << "Timing statistics for edge-expanded graph:"; @@ -477,6 +480,8 @@ void EdgeBasedGraphFactory::RenumberEdges() void EdgeBasedGraphFactory::GenerateEdgeBasedNodeData() { + BOOST_ASSERT(m_node_based_graph->GetNumberOfNodes() == m_node_based_graph_origin->GetNumberOfNodes()); + m_edge_based_node_data.resize(m_number_of_edge_based_nodes); std::vector<bool> found; found.resize(m_number_of_edge_based_nodes, false); @@ -486,21 +491,59 @@ void EdgeBasedGraphFactory::GenerateEdgeBasedNodeData() { for (EdgeID current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node)) { - EdgeData &edge_data = m_node_based_graph->GetEdgeData(current_edge); + EdgeData & edge_data = m_node_based_graph->GetEdgeData(current_edge); if (!edge_data.forward) { continue; } + NodeID target = m_node_based_graph->GetTarget(current_edge); - NodeData data; - data.lat1 = m_node_info_list[current_node].lat / COORDINATE_PRECISION; - data.lon1 = m_node_info_list[current_node].lon / COORDINATE_PRECISION; + osrm::NodeData data; + if (m_geometry_compressor.HasEntryForID(current_edge)) + { + const std::vector<GeometryCompressor::CompressedNode> & via_nodes = m_geometry_compressor.GetBucketReference(current_edge); + assert(via_nodes.size() > 0); + std::vector< std::pair< NodeID, FixedPointCoordinate > > nodes; + for (auto n : via_nodes) + nodes.emplace_back(n.first, FixedPointCoordinate(m_node_info_list[n.first].lat, m_node_info_list[n.first].lon)); + + for (uint32_t i = 0; i < nodes.size() - 1; ++i) + { + auto n1 = nodes[i]; + auto n2 = nodes[i + 1]; + + if (n1.first == n2.first) + { + SimpleLogger().Write() << "Error: Equal values " << n1.first << " and " << n2.first; + SimpleLogger().Write() << "i: "<< i << " nodes: " << nodes.size(); + throw std::exception(); + } + + EdgeID e = m_node_based_graph_origin->FindEdge(n1.first, n2.first); + if (e == SPECIAL_EDGEID) + { + SimpleLogger().Write() << "Error: Can't find edge between nodes " << n1.first << " and " << n2.first; + continue; + } - data.lat2 = m_node_info_list[target].lat / COORDINATE_PRECISION; - data.lon2 = m_node_info_list[target].lon / COORDINATE_PRECISION; + EdgeData &ed = m_node_based_graph_origin->GetEdgeData(e); + + data.AddSegment(ed.way_id, + m_node_info_list[n1.first].lat / COORDINATE_PRECISION, + m_node_info_list[n1.first].lon / COORDINATE_PRECISION, + m_node_info_list[n2.first].lat / COORDINATE_PRECISION, + m_node_info_list[n2.first].lon / COORDINATE_PRECISION); + } - data.way_id = edge_data.way_id; + } else + { + data.AddSegment(edge_data.way_id, + m_node_info_list[current_node].lat / COORDINATE_PRECISION, + m_node_info_list[current_node].lon / COORDINATE_PRECISION, + m_node_info_list[target].lat / COORDINATE_PRECISION, + m_node_info_list[target].lon / COORDINATE_PRECISION); + } if (found[edge_data.edgeBasedNodeID]) { @@ -692,6 +735,16 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg BOOST_ASSERT(edge_data1.forward); BOOST_ASSERT(edge_data2.forward); + if (edge_data1.way_id == 244396524) + { + SimpleLogger().Write() << " - Id: " << edge_data1.way_id << " n1: " << u << " n2: " << v; + } + + if (edge_data2.way_id == 244396524) + { + SimpleLogger().Write() << " - Id: " << edge_data2.way_id << " n1: " << v << " n2: " << w; + } + // the following is the core of the loop. unsigned distance = edge_data1.distance; if (m_traffic_lights.find(v) != m_traffic_lights.end()) diff --git a/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.h b/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.h index 02cd4b7a64..1a06a15c7d 100644 --- a/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.h +++ b/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.h @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../DataStructures/TurnInstructions.h" #include "../DataStructures/NodeBasedGraph.h" #include "../DataStructures/RestrictionMap.h" +#include "../DataStructures/EdgeBasedNodeData.h" #include "GeometryCompressor.h" #include <algorithm> @@ -49,6 +50,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <unordered_set> #include <vector> + struct lua_State; class EdgeBasedGraphFactory @@ -57,27 +59,10 @@ class EdgeBasedGraphFactory EdgeBasedGraphFactory() = delete; EdgeBasedGraphFactory(const EdgeBasedGraphFactory &) = delete; - struct NodeData - { - double lat1, lon1; - double lat2, lon2; - unsigned way_id; - - bool operator == (NodeData const & other) - { - return (way_id == other.way_id) && (lat1 == other.lat1) && (lon1 == other.lon1) - && (lat2 == other.lat2) && (lon2 == other.lon2); - } - - bool operator != (NodeData const & other) - { - return !(*this == other); - } - }; - struct SpeedProfileProperties; explicit EdgeBasedGraphFactory(const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph, + const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph_origin, std::unique_ptr<RestrictionMap> restricion_map, std::vector<NodeID> &barrier_node_list, std::vector<NodeID> &traffic_light_node_list, @@ -92,7 +77,7 @@ class EdgeBasedGraphFactory void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes); - void GetEdgeBasedNodeData(std::vector<NodeData> &data); + void GetEdgeBasedNodeData(osrm::NodeDataVectorT &data); TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, double angle) const; @@ -122,11 +107,12 @@ class EdgeBasedGraphFactory DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list; std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph; + std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph_origin; std::unordered_set<NodeID> m_barrier_nodes; std::unordered_set<NodeID> m_traffic_lights; std::unique_ptr<RestrictionMap> m_restriction_map; - std::vector<NodeData> m_edge_based_node_data; + std::vector<osrm::NodeData> m_edge_based_node_data; GeometryCompressor m_geometry_compressor; diff --git a/3party/osrm/osrm-backend/Contractor/Prepare.cpp b/3party/osrm/osrm-backend/Contractor/Prepare.cpp index dc9f1a9869..28f1e84d60 100644 --- a/3party/osrm/osrm-backend/Contractor/Prepare.cpp +++ b/3party/osrm/osrm-backend/Contractor/Prepare.cpp @@ -493,8 +493,13 @@ void Prepare::BuildEdgeExpandedGraph(lua_State *lua_state, NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list); std::unique_ptr<RestrictionMap> restriction_map = std::unique_ptr<RestrictionMap>(new RestrictionMap(node_based_graph, restriction_list)); + + std::shared_ptr<NodeBasedDynamicGraph> node_based_graph_origin = + NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list); + EdgeBasedGraphFactory *edge_based_graph_factory = new EdgeBasedGraphFactory(node_based_graph, + node_based_graph_origin, std::move(restriction_map), barrier_node_list, traffic_light_list, @@ -524,22 +529,12 @@ void Prepare::BuildEdgeExpandedGraph(lua_State *lua_state, edge_based_graph_factory->GetEdgeBasedNodes(node_based_edge_list); // serialize node data - std::vector<EdgeBasedGraphFactory::NodeData> data; + osrm::NodeDataVectorT data; edge_based_graph_factory->GetEdgeBasedNodeData(data); SimpleLogger().Write() << "Serialize node data"; - std::ofstream stream; - stream.open(node_data_filename); - if (!stream.is_open()) - { - SimpleLogger().Write() << "Can't open file " << node_data_filename; - throw std::exception(); - } - uint32_t count = data.size(); - stream.write((const char*)&count, sizeof(count)); - stream.write((const char*)(&data[0]), data.size() * sizeof(EdgeBasedGraphFactory::NodeData)); - stream.close(); + osrm::SaveNodeDataToFile(node_data_filename, data); delete edge_based_graph_factory; diff --git a/3party/osrm/osrm-backend/DataStructures/EdgeBasedNodeData.h b/3party/osrm/osrm-backend/DataStructures/EdgeBasedNodeData.h new file mode 100644 index 0000000000..dbcadfe01b --- /dev/null +++ b/3party/osrm/osrm-backend/DataStructures/EdgeBasedNodeData.h @@ -0,0 +1,123 @@ +#pragma once + +#include <stdint.h> +#include <vector> +#include <fstream> + + +namespace osrm +{ + +struct NodeData +{ +#pragma pack (push, 1) + struct SegmentInfo + { + uint64_t wayId; + double lat1, lon1, lat2, lon2; + + SegmentInfo() + : wayId(-1), lat1(-10000), lon1(-10000), lat2(-10000), lon2(-10000) + { + } + + SegmentInfo(uint64_t wayId, double lat1, double lon1, double lat2, double lon2) + : wayId(wayId), lat1(lat1), lon1(lon1), lat2(lat2), lon2(lon2) + { + } + + bool operator != (SegmentInfo const & other) const + { + return wayId != other.wayId || lat1 != other.lat1 || lon1 != other.lon1 || + lat2 != other.lat2 || lon2 != other.lon2; + } + }; +#pragma pack (pop) + + typedef std::vector<SegmentInfo> SegmentInfoVectorT; + SegmentInfoVectorT m_segments; + + NodeData() + { + } + + NodeData(SegmentInfoVectorT & vec) + { + m_segments.swap(vec); + } + + bool operator == (NodeData const & other) const + { + if (m_segments.size() != other.m_segments.size()) + return false; + + for (uint32_t i = 0; i < m_segments.size(); ++i) + if (m_segments[i] != other.m_segments[i]) + return false; + + return true; + } + + bool operator != (NodeData const & other) const + { + return !(*this == other); + } + + void AddSegment(uint64_t wayId, double lat1, double lon1, double lat2, double lon2) + { + m_segments.emplace_back(wayId, lat1, lon1, lat2, lon2); + } + + void SetSegments(SegmentInfoVectorT & segments) + { + m_segments.swap(segments); + } +}; + + +typedef std::vector<NodeData> NodeDataVectorT; + +inline bool SaveNodeDataToFile(std::string const & filename, NodeDataVectorT const & data) +{ + std::ofstream stream; + stream.open(filename); + if (!stream.is_open()) + return false; + + uint32_t count = data.size(); + stream.write((char*)&count, sizeof(count)); + for (auto d : data) + { + uint32_t pc = d.m_segments.size(); + stream.write((char*)&pc, sizeof(pc)); + stream.write((char*)d.m_segments.data(), sizeof(NodeData::SegmentInfo) * pc); + } + stream.close(); + return true; +} + +inline bool LoadNodeDataFromFile(std::string const & filename, NodeDataVectorT & data) +{ + std::ifstream stream; + stream.open(filename); + if (!stream.is_open()) + return false; + + uint32_t count = 0; + stream.read((char*)&count, sizeof(count)); + for (uint32_t i = 0; i < count; ++i) + { + uint32_t pc; + stream.read((char*)&pc, sizeof(pc)); + NodeData::SegmentInfoVectorT segments; + segments.resize(pc); + stream.read((char*)segments.data(), sizeof(NodeData::SegmentInfo) * pc); + + data.emplace_back(segments); + } + stream.close(); + + return true; +} + +} diff --git a/generator/routing_generator.cpp b/generator/routing_generator.cpp index 1f09c27bba..d1a6fa1bf8 100644 --- a/generator/routing_generator.cpp +++ b/generator/routing_generator.cpp @@ -1,39 +1,30 @@ #include "routing_generator.hpp" +#include "gen_mwm_info.hpp" #include "../indexer/index.hpp" #include "../indexer/classificator_loader.hpp" #include "../indexer/feature.hpp" #include "../indexer/ftypes_matcher.hpp" +#include "../indexer/mercator.hpp" -#include "../3party/osrm/osrm-backend/DataStructures/QueryEdge.h" -#include "../3party/osrm/osrm-backend/Server/DataStructures/InternalDataFacade.h" +#include "../geometry/distance_on_sphere.hpp" -namespace routing -{ +#include "../routing/osrm_data_facade_types.hpp" -uint32_t const MAX_SCALE = 15; // max scale for roads +#include "../platform/platform.hpp" -struct Node2Feature -{ - NodeID m_nodeId; - FeatureID m_FID; - uint32_t m_start; - uint32_t m_len; +#include "../base/logging.hpp" - Node2Feature(NodeID nodeId, FeatureID fid, uint32_t start, uint32_t len) - : m_nodeId(nodeId), m_FID(fid), m_start(start), m_len(len) - { - } -}; +#include "../std/fstream.hpp" + +#include "../3party/osrm/osrm-backend/DataStructures/EdgeBasedNodeData.h" -struct Node2FeatureSetComp + +namespace routing { - bool operator() (Node2Feature const & a, Node2Feature const & b) - { - return a.m_nodeId < b.m_nodeId; - } -}; -typedef std::set<Node2Feature, Node2FeatureSetComp> Node2FeatureSet; + + +double const EQUAL_POINT_RADIUS_M = 1; void GenerateNodesInfo(string const & mwmName, string const & osrmName) { @@ -47,73 +38,110 @@ void GenerateNodesInfo(string const & mwmName, string const & osrmName) return; } - ServerPaths server_paths; - server_paths["hsgrdata"] = boost::filesystem::path(osrmName + ".hsgr"); - server_paths["ramindex"] = boost::filesystem::path(osrmName + ".ramIndex"); - server_paths["fileindex"] = boost::filesystem::path(osrmName + ".fileIndex"); - server_paths["geometries"] = boost::filesystem::path(osrmName + ".geometry"); - server_paths["nodesdata"] = boost::filesystem::path(osrmName + ".nodes"); - server_paths["edgesdata"] = boost::filesystem::path(osrmName + ".edges"); - server_paths["namesdata"] = boost::filesystem::path(osrmName + ".names"); - server_paths["timestamp"] = boost::filesystem::path(osrmName + ".timestamp"); - - InternalDataFacade<QueryEdge::EdgeData> facade(server_paths); - - Node2FeatureSet nodesSet; - uint32_t processed = 0; - auto fn = [&](FeatureType const & ft) + Platform & pl = GetPlatform(); + + gen::OsmID2FeatureID osm2ft; { - processed++; + ReaderSource<ModelReaderPtr> src(pl.GetReader(mwmName + OSM2FEATURE_FILE_EXTENSION)); + osm2ft.Read(src); + } - if (processed % 1000 == 0) - { - if (processed % 10000 == 0) - std::cout << "[" << processed / 1000 << "k]"; - else - std::cout << "."; - std::cout.flush(); - } + string nodeFileName = osrmName + ".nodeData"; - feature::TypesHolder types(ft); - if (types.GetGeoType() != feature::GEOM_LINE) - return; + OsrmFtSegMapping mapping; - if (!ftypes::IsStreetChecker::Instance()(ft)) - return; + ifstream input; + input.open(nodeFileName); + if (!input.is_open()) + { + LOG(LERROR, ("Can't open file ", nodeFileName)); + return; + } - std::cout << "------------ FID: " << ft.GetID().m_offset << std::endl; + osrm::NodeDataVectorT nodeData; + if (!osrm::LoadNodeDataFromFile(nodeFileName, nodeData)) + { + LOG(LERROR, ("Can't load node data")); + return; + } - ft.ParseGeometry(FeatureType::BEST_GEOMETRY); - uint32_t lastId = std::numeric_limits<uint32_t>::max(); - uint32_t start = 0; - for (uint32_t i = 1; i < ft.GetPointsCount(); ++i) + uint32_t found = 0, all = 0; + uint32_t nodeId = 0; + for (osrm::NodeData data : nodeData) + { + uint32_t segId = 0; + OsrmFtSegMapping::FtSegVectorT vec; + vec.resize(data.m_segments.size()); + + for (auto seg : data.m_segments) { - m2::PointD p = ft.GetPoint(i -1).mid(ft.GetPoint(i)); - FixedPointCoordinate fp(static_cast<int>(p.x * COORDINATE_PRECISION), - static_cast<int>(p.y * COORDINATE_PRECISION)); + m2::PointD pts[2] = {{seg.lon1, seg.lat1}, {seg.lon2, seg.lat2}}; + + all++; - PhantomNode node; - if (facade.FindPhantomNodeForCoordinate(fp, node, 18)) + // now need to determine feature id and segments in it + uint32_t const fID = osm2ft.GetFeatureID(seg.wayId); + if (fID == 0) { - if (node.forward_node_id != lastId) + LOG(LWARNING, ("No feature id for way:", seg.wayId)); + continue; + } + + FeatureType ft; + Index::FeaturesLoaderGuard loader(index, 0); + loader.GetFeature(fID, ft); + + ft.ParseGeometry(FeatureType::BEST_GEOMETRY); + int32_t indicies[2] = {-1, -1}; + + for (uint32_t j = 0; j < ft.GetPointsCount(); ++j) + { + double lon = MercatorBounds::XToLon(ft.GetPoint(j).x); + double lat = MercatorBounds::YToLat(ft.GetPoint(j).y); + for (uint32_t k = 0; k < 2; ++k) { - if (lastId != std::numeric_limits<uint32_t>::max()) + double const dist = ms::DistanceOnEarth(pts[k].y, pts[k].x, lat, lon); + //LOG(LINFO, ("Distance: ", dist)); + + if (dist <= EQUAL_POINT_RADIUS_M) { - bool added = nodesSet.insert(Node2Feature(node.forward_node_id, ft.GetID(), start, i - 1)).second; - assert(added); + //ASSERT_EQUAL(indicies[k], -1, ()); + indicies[k] = j; } - lastId = node.forward_node_id; - start = i - 1; - std::cout << "LastID: " << lastId << " ForwardID: " << node.forward_node_id << " Offset: " << node.forward_offset << std::endl; } - } else - break; - } - }; - index.ForEachInRect(fn, MercatorBounds::FullRect(), MAX_SCALE); + } + + // Check if indicies found + if (indicies[0] != -1 && indicies[1] != -1) + { + found++; + ASSERT_NOT_EQUAL(indicies[0], indicies[1], ()); + OsrmFtSegMapping::FtSeg & segData = vec[segId++]; + segData.m_fid = fID; + segData.m_pointEnd = indicies[1]; + segData.m_pointStart = indicies[0]; + mapping.Append(nodeId++, vec); + } + else + { + LOG(LINFO, ("----------------- Way ID: ", seg.wayId, "--- Segments: ", data.m_segments.size(), " SegId: ", segId)); + LOG(LINFO, ("P1: ", pts[0].y, " ", pts[0].x, " P2: ", pts[1].y, " ", pts[1].x)); + for (uint32_t j = 0; j < ft.GetPointsCount(); ++j) + { + double lon = MercatorBounds::XToLon(ft.GetPoint(j).x); + double lat = MercatorBounds::YToLat(ft.GetPoint(j).y); + double const dist1 = ms::DistanceOnEarth(pts[0].y, pts[0].x, lat, lon); + double const dist2 = ms::DistanceOnEarth(pts[1].y, pts[1].x, lat, lon); + LOG(LINFO, ("p", j, ": ", lat, ", ", lon, " Dist1: ", dist1, " Dist2: ", dist2)); + } + } + - std::cout << "Nodes: " << facade.GetNumberOfNodes() << " Set: " << nodesSet.size() << std::endl; + } + } + LOG(LINFO, ("Found: ", found, " All: ", all)); + mapping.Save(osrmName + ".ftseg"); } } diff --git a/generator/routing_generator.hpp b/generator/routing_generator.hpp index d32f287184..6e63317cdd 100644 --- a/generator/routing_generator.hpp +++ b/generator/routing_generator.hpp @@ -1,9 +1,11 @@ #pragma once #include "../std/string.hpp" +#include "../std/vector.hpp" namespace routing { void GenerateNodesInfo(string const & mwmName, string const & osrmName); + } diff --git a/routing/osrm_data_facade_types.hpp b/routing/osrm_data_facade_types.hpp new file mode 100644 index 0000000000..52f2f4ffa0 --- /dev/null +++ b/routing/osrm_data_facade_types.hpp @@ -0,0 +1,119 @@ +#pragma once + +#include "../base/assert.hpp" +#include "../std/string.hpp" +#include "../std/vector.hpp" +#include "../std/fstream.hpp" +#include "../std/unordered_map.hpp" + +namespace routing +{ + +#define SPECIAL_OSRM_NODE_ID -1 +typedef uint32_t OsrmNodeIdT; + +class OsrmFtSegMapping +{ +public: + + struct FtSeg + { + uint32_t m_fid; + uint32_t m_pointStart; + uint32_t m_pointEnd; + }; + + typedef vector<FtSeg> FtSegVectorT; + + void Save(string const & filename) + { + ofstream stream; + stream.open(filename); + + if (!stream.is_open()) + return; + + uint32_t count = m_osrm2FtSeg.size(); + stream.write((char*)&count, sizeof(count)); + + for (uint32_t i = 0; i < count; ++i) + { + auto it = m_osrm2FtSeg.find(i); + CHECK(it != m_osrm2FtSeg.end(), ()); + FtSegVectorT const & v = it->second; + + uint32_t vc = v.size(); + stream.write((char*)&vc, sizeof(vc)); + stream.write((char*)v.data(), sizeof(OsrmFtSegMapping::FtSeg) * vc); + } + + stream.close(); + } + + void Load(string const & filename) + { + ifstream stream; + stream.open(filename); + + if (!stream.is_open()) + return; + + uint32_t count = 0; + stream.read((char*)&count, sizeof(count)); + + for (uint32_t i = 0; i < count; ++i) + { + uint32_t vc = 0; + stream.read((char*)&vc, sizeof(vc)); + + FtSegVectorT v; + v.resize(vc); + stream.read((char*)v.data(), sizeof(FtSeg) * vc); + + m_osrm2FtSeg[i] = v; + } + + stream.close(); + } + + void Append(OsrmNodeIdT osrmNodeId, FtSegVectorT & data) + { + ASSERT(m_osrm2FtSeg.find(osrmNodeId) == m_osrm2FtSeg.end(), ()); + m_osrm2FtSeg[osrmNodeId] = data; + } + + FtSegVectorT const & GetSegVector(OsrmNodeIdT nodeId) const + { + auto it = m_osrm2FtSeg.find(nodeId); + ASSERT(it != m_osrm2FtSeg.end(), ()); + return it->second; + } + + void GetOsrmNode(FtSeg const & seg, OsrmNodeIdT & forward, OsrmNodeIdT & reverse) const + { + forward = SPECIAL_OSRM_NODE_ID; + reverse = SPECIAL_OSRM_NODE_ID; + + for (unordered_map<OsrmNodeIdT, FtSegVectorT>::const_iterator it = m_osrm2FtSeg.begin(); it != m_osrm2FtSeg.end(); ++it) + { + for (auto s : it->second) + { + if (s.m_pointStart <= s.m_pointEnd) + { + if (seg.m_pointStart >= s.m_pointStart && seg.m_pointEnd <= s.m_pointEnd) + forward = it->first; + } + else + { + if (seg.m_pointStart >= s.m_pointEnd && seg.m_pointEnd <= s.m_pointStart) + reverse = it->first; + } + } + } + } + +private: + unordered_map<OsrmNodeIdT, FtSegVectorT> m_osrm2FtSeg; +}; + +} diff --git a/routing/routing.pro b/routing/routing.pro index 995b084f09..acc2756d5d 100644 --- a/routing/routing.pro +++ b/routing/routing.pro @@ -31,6 +31,7 @@ HEADERS += \ osrm_router.hpp \ osrm_online_router.hpp \ osrm_data_facade.hpp \ + osrm_data_facade_types.hpp \ road_graph_router.hpp \ dijkstra_router.hpp \ features_road_graph.hpp \ |