forked from organicmaps/organicmaps
[routing] [generator] Using Mapping file container for routing index.
This commit is contained in:
parent
718b5bba6d
commit
acbbd3c8b7
7 changed files with 131 additions and 79 deletions
|
@ -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"
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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 EdgeDataT> class OsrmDataFacade : public BaseDataFacade<EdgeData
|
|||
{
|
||||
typedef BaseDataFacade<EdgeDataT> 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 <typename T>
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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<FtSeg> 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<uint32_t const *>(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<uint32_t const *>(data);
|
||||
data += sizeof(vc);
|
||||
|
||||
FtSegVectorT v;
|
||||
v.resize(vc);
|
||||
stream.read((char*)v.data(), sizeof(FtSeg) * vc);
|
||||
FtSeg const * seg = reinterpret_cast<FtSeg const *>(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)
|
||||
|
|
|
@ -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<QueryEdge::EdgeData> 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<DataFacadeT> 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<QueryEdge::EdgeData> DataFacadeT;
|
||||
DataFacadeT facade(container);
|
||||
m_mapping.Load(container);
|
||||
|
||||
SearchEngineData engineData;
|
||||
ShortestPathRouting<DataFacadeT> 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);
|
||||
|
||||
|
|
|
@ -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<string (m2::PointD const &)> 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;
|
||||
|
|
Loading…
Add table
Reference in a new issue