[routing] [generator] Using Mapping file container for routing index.

This commit is contained in:
Denis Koronchik 2014-09-16 19:05:16 +03:00 committed by Alex Zolotarev
parent 718b5bba6d
commit acbbd3c8b7
7 changed files with 131 additions and 79 deletions

View file

@ -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"

View file

@ -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()));
}
}
}

View file

@ -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()));
}

View file

@ -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();
}

View file

@ -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)

View file

@ -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);

View file

@ -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;