diff --git a/defines.hpp b/defines.hpp index 146ea96bc7..ef4b9b8989 100644 --- a/defines.hpp +++ b/defines.hpp @@ -12,11 +12,17 @@ #define SEARCH_INDEX_FILE_TAG "sdx" #define HEADER_FILE_TAG "header" #define VERSION_FILE_TAG "version" +#define ROUTING_MATRIX_FILE_TAG "matrix" +#define ROUTING_EDGEDATA_FILE_TAG "edgedata" +#define ROUTING_EDGEID_FILE_TAG "edgeid" +#define ROUTING_SHORTCUTS_FILE_TAG "shortcuts" +#define ROUTING_FTSEG_FILE_TAG "ftseg" #define READY_FILE_EXTENSION ".ready" #define RESUME_FILE_EXTENSION ".resume3" #define DOWNLOADING_FILE_EXTENSION ".downloading3" #define BOOKMARKS_FILE_EXTENSION ".kml" +#define ROUTING_FILE_EXTENSION ".routing" #define COUNTRIES_FILE "countries.txt" #define GUIDES_DATA_FILE_SUFFIX "guides.json" diff --git a/generator/routing_generator.cpp b/generator/routing_generator.cpp index 3718da52ac..5496acdda5 100644 --- a/generator/routing_generator.cpp +++ b/generator/routing_generator.cpp @@ -1,6 +1,8 @@ #include "routing_generator.hpp" #include "gen_mwm_info.hpp" +#include "../coding/file_container.hpp" + #include "../indexer/index.hpp" #include "../indexer/classificator_loader.hpp" #include "../indexer/feature.hpp" @@ -188,7 +190,34 @@ void GenerateNodesInfo(string const & mwmName, string const & osrmName) LOG(LINFO, ("All:", all, "Found:", found, "Not found:", all - found, "More that one segs in node:", moreThan1Seg, "Multiple:", multiple, "Equal:", equal)); - mapping.Save(osrmName + ".ftseg"); + + mapping.Save(osrmName + "." + ROUTING_FTSEG_FILE_TAG); + + LOG(LINFO, ("Collect all data into one file...")); + + try + { + FilesContainerW writer(mwmName + ROUTING_FILE_EXTENSION); + + auto appendFile = [&] (string const & tag) + { + string const fileName = osrmName + "." + tag; + LOG(LINFO, ("Append file", fileName, "with tag", tag)); + writer.Write(fileName, tag); + }; + + appendFile(ROUTING_SHORTCUTS_FILE_TAG); + appendFile(ROUTING_EDGEDATA_FILE_TAG); + appendFile(ROUTING_MATRIX_FILE_TAG); + appendFile(ROUTING_EDGEID_FILE_TAG); + appendFile(ROUTING_FTSEG_FILE_TAG); + + writer.Finish(); + } + catch (RootException const & ex) + { + LOG(LCRITICAL, ("Can't write routing index", ex.Msg())); + } } } diff --git a/map/framework.cpp b/map/framework.cpp index 5fc90e7087..4910a77fa6 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -254,7 +254,10 @@ Framework::Framework() LOG(LDEBUG, ("Guides info initialized")); #endif - m_routingSession.SetRouter(new routing::OsrmRouter(&m_model.GetIndex())); + m_routingSession.SetRouter(new routing::OsrmRouter(&m_model.GetIndex(), [this] (m2::PointD const & pt) + { + return GetSearchEngine()->GetCountryFile(pt); + }); LOG(LINFO, ("System languages:", languages::GetPreferred())); } diff --git a/routing/osrm_data_facade.hpp b/routing/osrm_data_facade.hpp index 23f80d8ee1..e9f9130437 100644 --- a/routing/osrm_data_facade.hpp +++ b/routing/osrm_data_facade.hpp @@ -1,19 +1,18 @@ #pragma once +#include "../defines.hpp" + #include "../std/string.hpp" -#include "../std/vector.hpp" -#include "../std/iostream.hpp" + +#include "../coding/file_container.hpp" #include "../../../succinct/elias_fano.hpp" #include "../../../succinct/gamma_vector.hpp" #include "../../../succinct/bit_vector.hpp" #include "../../../succinct/mapper.hpp" -//#include "../3party/osrm/osrm-backend/DataStructures/RangeTable.h" -#include "../3party/osrm/osrm-backend/DataStructures/StaticRTree.h" -#include "../3party/osrm/osrm-backend/DataStructures/EdgeBasedNode.h" #include "../3party/osrm/osrm-backend/Server/DataStructures/BaseDataFacade.h" -#include "../3party/osrm/osrm-backend/DataStructures/OriginalEdgeData.h" + namespace routing { @@ -22,53 +21,49 @@ template class OsrmDataFacade : public BaseDataFacade super; - boost::iostreams::mapped_file_source m_edgeDataSource; succinct::gamma_vector m_edgeData; - boost::iostreams::mapped_file_source m_edgeIdSource; succinct::gamma_vector m_edgeId; - boost::iostreams::mapped_file_source m_shortcutsSource; succinct::bit_vector m_shortcuts; - succinct::elias_fano m_fanoMatrix; - boost::iostreams::mapped_file_source m_fanoSource; + + FilesMappingContainer const & m_container; + + FilesMappingContainer::Handle m_handleEdgeData; + FilesMappingContainer::Handle m_handleEdgeId; + FilesMappingContainer::Handle m_handleShortcuts; + FilesMappingContainer::Handle m_handleFanoMatrix; unsigned m_numberOfNodes; public: - template - void loadFromFile(T & v, string const & fileName) + OsrmDataFacade(FilesMappingContainer const & container) + : m_container(container) { - std::ifstream stream; - stream.open(fileName); - v.load(stream); - stream.close(); - } + m_handleEdgeData = m_container.Map(ROUTING_EDGEDATA_FILE_TAG); + ASSERT(m_handleEdgeData.IsValid(), ()); + succinct::mapper::map(m_edgeData, m_handleEdgeData.GetData()); - OsrmDataFacade(string const & fileName) - { - m_edgeDataSource.open(fileName + ".edgedata"); - succinct::mapper::map(m_edgeData, m_edgeDataSource); + m_handleEdgeId = m_container.Map(ROUTING_EDGEID_FILE_TAG); + ASSERT(m_handleEdgeId.IsValid(), ()); + succinct::mapper::map(m_edgeId, m_handleEdgeId.GetData()); - m_edgeIdSource.open(fileName + ".edgeid"); - succinct::mapper::map(m_edgeId, m_edgeIdSource); + m_handleShortcuts = m_container.Map(ROUTING_SHORTCUTS_FILE_TAG); + ASSERT(m_handleShortcuts.IsValid(), ()); + succinct::mapper::map(m_shortcuts, m_handleShortcuts.GetData()); - m_shortcutsSource.open(fileName + ".shortcuts"); - succinct::mapper::map(m_shortcuts, m_shortcutsSource); + m_handleFanoMatrix = m_container.Map(ROUTING_MATRIX_FILE_TAG); + ASSERT(m_handleFanoMatrix.IsValid(), ()); + succinct::mapper::map(m_fanoMatrix, m_handleFanoMatrix.GetData()); - m_fanoSource.open(fileName + ".matrix"); - succinct::mapper::map(m_fanoMatrix, m_fanoSource); - - - //std::cout << m_fanoMatrix.size() << std::endl; m_numberOfNodes = (unsigned)sqrt(m_fanoMatrix.size() / 2) + 1; } ~OsrmDataFacade() { - m_edgeDataSource.close(); - m_edgeIdSource.close(); - m_shortcutsSource.close(); - m_fanoSource.close(); + m_handleEdgeData.Unmap(); + m_handleEdgeId.Unmap(); + m_handleFanoMatrix.Unmap(); + m_handleShortcuts.Unmap(); } diff --git a/routing/osrm_data_facade_types.hpp b/routing/osrm_data_facade_types.hpp index 87f72e5934..4ed566e267 100644 --- a/routing/osrm_data_facade_types.hpp +++ b/routing/osrm_data_facade_types.hpp @@ -1,8 +1,12 @@ #pragma once +#include "../defines.hpp" + #include "../base/assert.hpp" #include "../base/logging.hpp" +#include "../coding/file_container.hpp" + #include "../std/string.hpp" #include "../std/vector.hpp" #include "../std/fstream.hpp" @@ -20,6 +24,11 @@ class OsrmFtSegMapping { public: + OsrmFtSegMapping() + { + } + +#pragma pack (push, 1) struct FtSeg { uint32_t m_fid; @@ -99,6 +108,7 @@ public: return ss.str(); } }; +#pragma pack (pop) typedef vector FtSegVectorT; @@ -110,7 +120,7 @@ public: if (!stream.is_open()) return; - uint32_t count = m_osrm2FtSeg.size(); + uint32_t const count = m_osrm2FtSeg.size(); stream.write((char*)&count, sizeof(count)); for (uint32_t i = 0; i < count; ++i) @@ -119,38 +129,36 @@ public: CHECK(it != m_osrm2FtSeg.end(), ()); FtSegVectorT const & v = it->second; - uint32_t vc = v.size(); + uint32_t const vc = v.size(); stream.write((char*)&vc, sizeof(vc)); - stream.write((char*)v.data(), sizeof(OsrmFtSegMapping::FtSeg) * vc); + stream.write((char*)v.data(), sizeof(FtSeg) * vc); } stream.close(); } - void Load(string const & filename) + void Load(FilesMappingContainer & container) { - ifstream stream; - stream.open(filename); + FilesMappingContainer::Handle handle = container.Map(ROUTING_FTSEG_FILE_TAG); - if (!stream.is_open()) - return; + char const * data = handle.GetData(); - uint32_t count = 0; - stream.read((char*)&count, sizeof(count)); + uint32_t const count = *reinterpret_cast(data); + data += sizeof(count); for (uint32_t i = 0; i < count; ++i) { - uint32_t vc = 0; - stream.read((char*)&vc, sizeof(vc)); + uint32_t const vc = *reinterpret_cast(data); + data += sizeof(vc); - FtSegVectorT v; - v.resize(vc); - stream.read((char*)v.data(), sizeof(FtSeg) * vc); + FtSeg const * seg = reinterpret_cast(data); + FtSegVectorT v(seg, seg + vc); + m_osrm2FtSeg[i].swap(v); - m_osrm2FtSeg[i] = v; + data += sizeof(FtSeg) * vc; } - stream.close(); + handle.Unmap(); } void Append(OsrmNodeIdT osrmNodeId, FtSegVectorT & data) diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp index cde47a1ee1..37612f4afb 100644 --- a/routing/osrm_router.cpp +++ b/routing/osrm_router.cpp @@ -115,8 +115,8 @@ public: // ---------------- -OsrmRouter::OsrmRouter(Index const * index) - : m_pIndex(index) +OsrmRouter::OsrmRouter(Index const * index, CountryFileFnT const & fn) + : m_pIndex(index), m_countryFn(fn) { } @@ -165,30 +165,33 @@ public: void OsrmRouter::CalculateRoute(m2::PointD const & startingPt, ReadyCallback const & callback) { - typedef OsrmDataFacade DataFacadeT; - - string const country = "Belarus"; -#ifdef OMIM_OS_DESKTOP - DataFacadeT facade("/Users/deniskoronchik/Documents/develop/omim-maps/" + country + ".osrm"); - m_mapping.Load("/Users/deniskoronchik/Documents/develop/omim-maps/" + country + ".osrm.ftseg"); -#else - DataFacadeT facade(GetPlatform().WritablePathForFile(country + ".osrm")); - m_mapping.Load(GetPlatform().WritablePathForFile(country + ".osrm.ftseg")); -#endif - - SearchEngineData engine_working_data; - ShortestPathRouting shortest_path(&facade, engine_working_data); - - RawRouteData rawRoute; - PhantomNodes nodes; MakeResultGuard resGuard(callback, GetName()); + string const fName = m_countryFn(startingPt); + if (fName != m_countryFn(m_finalPt)) + { + resGuard.SetErrorMsg("Points are in different MWMs"); + return; + } + + FilesMappingContainer container(GetPlatform().WritablePathForFile(fName + DATA_FILE_EXTENSION + ROUTING_FILE_EXTENSION)); + + typedef OsrmDataFacade DataFacadeT; + DataFacadeT facade(container); + m_mapping.Load(container); + + SearchEngineData engineData; + ShortestPathRouting pathFinder(&facade, engineData); + RawRouteData rawRoute; + + PhantomNodes nodes; + OsrmFtSegMapping::FtSeg segBegin; m2::PointD segPointStart; uint32_t mwmIdStart = -1; if (!FindPhantomNode(startingPt, nodes.source_phantom, mwmIdStart, segBegin, segPointStart)) { - resGuard.SetErrorMsg("Can't find start point"); + resGuard.SetErrorMsg("Can't find start point node"); return; } @@ -197,19 +200,19 @@ void OsrmRouter::CalculateRoute(m2::PointD const & startingPt, ReadyCallback con m2::PointD segPointEnd; if (!FindPhantomNode(m_finalPt, nodes.target_phantom, mwmIdEnd, segEnd, segPointEnd)) { - resGuard.SetErrorMsg("Can't find end point"); + resGuard.SetErrorMsg("Can't find end point node"); return; } if (mwmIdEnd != mwmIdStart || mwmIdEnd == -1 || mwmIdStart == -1) { - resGuard.SetErrorMsg("Points in different MWMs"); + resGuard.SetErrorMsg("Founded features are in different MWMs"); return; } rawRoute.segment_end_coordinates.push_back(nodes); - shortest_path({nodes}, {}, rawRoute); + pathFinder({nodes}, {}, rawRoute); if (INVALID_EDGE_WEIGHT == rawRoute.shortest_path_length || rawRoute.segment_end_coordinates.empty() @@ -289,7 +292,8 @@ void OsrmRouter::CalculateRoute(m2::PointD const & startingPt, ReadyCallback con resGuard.SetGeometry(points); } -bool OsrmRouter::FindPhantomNode(m2::PointD const & pt, PhantomNode & resultNode, uint32_t & mwmId, OsrmFtSegMapping::FtSeg & seg, m2::PointD & segPt) +bool OsrmRouter::FindPhantomNode(m2::PointD const & pt, PhantomNode & resultNode, + uint32_t & mwmId, OsrmFtSegMapping::FtSeg & seg, m2::PointD & segPt) { Point2PhantomNode getter(pt, m_mapping); diff --git a/routing/osrm_router.hpp b/routing/osrm_router.hpp index 8c1ebbb8e9..00673319f4 100644 --- a/routing/osrm_router.hpp +++ b/routing/osrm_router.hpp @@ -3,6 +3,9 @@ #include "router.hpp" #include "osrm_data_facade_types.hpp" +#include "../std/function.hpp" + + class Index; struct PhantomNode; @@ -13,8 +16,11 @@ class OsrmRouter : public IRouter { m2::PointD m_finalPt; + typedef function CountryFileFnT; + CountryFileFnT m_countryFn; + public: - OsrmRouter(Index const * index); + OsrmRouter(Index const * index, CountryFileFnT const & fn); virtual string GetName() const; virtual void SetFinalPoint(m2::PointD const & finalPt); @@ -22,7 +28,8 @@ public: protected: - bool FindPhantomNode(m2::PointD const & pt, PhantomNode & resultNode, uint32_t & mwmId, OsrmFtSegMapping::FtSeg & seg, m2::PointD & segPt); + bool FindPhantomNode(m2::PointD const & pt, PhantomNode & resultNode, uint32_t & mwmId, + OsrmFtSegMapping::FtSeg & seg, m2::PointD & segPt); private: Index const * m_pIndex;