BREAKING CHANGE, REPROCESS YOUR OSM FILES
All preparations necessary to compute and output turn directions.
This commit is contained in:
parent
4c47d5b70e
commit
676f64b0ef
@ -75,6 +75,7 @@ public:
|
||||
bool shortcut : 1;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
short type;
|
||||
_MiddleName middleName;
|
||||
} data;
|
||||
|
||||
@ -121,10 +122,10 @@ public:
|
||||
|
||||
newEdge.data.distance = _graph[edge].data.distance;
|
||||
newEdge.data.shortcut = _graph[edge].data.shortcut;
|
||||
if ( newEdge.data.shortcut )
|
||||
newEdge.data.middleName = _graph[edge].data.middleName;
|
||||
newEdge.data.forward = _graph[edge].data.forward;
|
||||
newEdge.data.backward = _graph[edge].data.backward;
|
||||
newEdge.data.type = _graph[edge].data.type;
|
||||
edges.push_back( newEdge );
|
||||
}
|
||||
#ifdef _GLIBCXX_PARALLEL
|
||||
|
@ -58,6 +58,7 @@ private:
|
||||
bool shortcut : 1;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
short type;
|
||||
_MiddleName middleName;
|
||||
} data;
|
||||
|
||||
@ -199,6 +200,7 @@ public:
|
||||
}
|
||||
edge.data.shortcut = false;
|
||||
edge.data.middleName.nameID = i->name();
|
||||
edge.data.type = i->type();
|
||||
edge.data.forward = i->isForward();
|
||||
edge.data.backward = i->isBackward();
|
||||
edge.data.originalEdges = 1;
|
||||
@ -218,6 +220,9 @@ public:
|
||||
for ( NodeID i = 0; i < edges.size(); ) {
|
||||
const NodeID source = edges[i].source;
|
||||
const NodeID target = edges[i].target;
|
||||
const NodeID middle = edges[i].data.middleName.nameID;
|
||||
const short type = edges[i].data.type;
|
||||
assert(type >= 0);
|
||||
//remove eigenloops
|
||||
if ( source == target ) {
|
||||
i++;
|
||||
@ -229,7 +234,8 @@ public:
|
||||
forwardEdge.target = backwardEdge.target = target;
|
||||
forwardEdge.data.forward = backwardEdge.data.backward = true;
|
||||
forwardEdge.data.backward = backwardEdge.data.forward = false;
|
||||
forwardEdge.data.middleName.nameID = backwardEdge.data.middleName.nameID = 0;
|
||||
forwardEdge.data.type = backwardEdge.data.type = type;
|
||||
forwardEdge.data.middleName.nameID = backwardEdge.data.middleName.nameID = middle;
|
||||
forwardEdge.data.shortcut = backwardEdge.data.shortcut = false;
|
||||
forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1;
|
||||
forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max();
|
||||
@ -457,7 +463,15 @@ public:
|
||||
newEdge.target = target;
|
||||
newEdge.data.distance = data.distance;
|
||||
newEdge.data.shortcut = data.shortcut;
|
||||
if(data.shortcut) {
|
||||
newEdge.data.middleName.middle = data.middleName.middle;
|
||||
newEdge.data.type = -1;
|
||||
} else {
|
||||
newEdge.data.middleName.nameID = data.middleName.nameID;
|
||||
newEdge.data.type = data.type;
|
||||
assert(newEdge.data.type >= 0);
|
||||
}
|
||||
|
||||
newEdge.data.forward = data.forward;
|
||||
newEdge.data.backward = data.backward;
|
||||
edges.push_back( newEdge );
|
||||
@ -546,9 +560,6 @@ private:
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
//can't rely on that, because we save the nameID instead
|
||||
assert(data.middleName.nameID == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -557,7 +568,6 @@ private:
|
||||
|
||||
template< bool Simulate > bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) {
|
||||
_Heap& heap = data->heap;
|
||||
//std::vector< Witness >& witnessList = data->witnessList;
|
||||
|
||||
for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) {
|
||||
const _EdgeData& inData = _graph->GetEdgeData( inEdge );
|
||||
|
@ -45,7 +45,7 @@ template<typename EdgeT>
|
||||
NodeID readOSRMGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<NodeInfo> * int2ExtNodeMap) {
|
||||
NodeID n, source, target, id;
|
||||
EdgeID m;
|
||||
bool locatable;
|
||||
short locatable;
|
||||
int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open)
|
||||
ExternalNodeMap ext2IntNodeMap;
|
||||
ext2IntNodeMap.set_empty_key(UINT_MAX);
|
||||
@ -62,9 +62,10 @@ NodeID readOSRMGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<Node
|
||||
edgeList.reserve(m);
|
||||
for (EdgeID i=0; i<m; i++) {
|
||||
EdgeWeight weight;
|
||||
short type;
|
||||
NodeID nameID;
|
||||
int length;
|
||||
in >> source >> target >> length >> dir >> weight >> locatable;
|
||||
|
||||
in >> source >> target >> length >> dir >> weight >> type >> nameID;
|
||||
assert(length > 0);
|
||||
assert(weight > 0);
|
||||
assert(0<=dir && dir<=2);
|
||||
@ -92,7 +93,7 @@ NodeID readOSRMGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<Node
|
||||
|
||||
if(source == UINT_MAX || target == UINT_MAX) { cerr << "nonexisting source or target" << endl; exit(0); }
|
||||
|
||||
EdgeT inputEdge(source, target, edgeList.size(), weight, forward, backward, locatable);
|
||||
EdgeT inputEdge(source, target, nameID, weight, forward, backward, type );
|
||||
edgeList.push_back(inputEdge);
|
||||
}
|
||||
ext2IntNodeMap.clear();
|
||||
@ -112,6 +113,7 @@ void readHSGRFromStream(istream &in, vector<EdgeT> * edgeList) {
|
||||
bool shortcut;
|
||||
bool forward;
|
||||
bool backward;
|
||||
short type;
|
||||
NodeID middle;
|
||||
NodeID source;
|
||||
NodeID target;
|
||||
@ -122,9 +124,10 @@ void readHSGRFromStream(istream &in, vector<EdgeT> * edgeList) {
|
||||
in.read((char *)&(forward), sizeof(bool));
|
||||
in.read((char *)&(backward), sizeof(bool));
|
||||
in.read((char *)&(middle), sizeof(NodeID));
|
||||
in.read((char *)&(type), sizeof(short));
|
||||
in.read((char *)&(source), sizeof(NodeID));
|
||||
in.read((char *)&(target), sizeof(NodeID));
|
||||
e.backward = backward; e.distance = distance; e.forward = forward; e.middleName.middle = middle; e.shortcut = shortcut;
|
||||
e.backward = backward; e.distance = distance; e.forward = forward; e.middleName.middle = middle; e.shortcut = shortcut; e.type = type;
|
||||
g.data = e; g.source = source; g.target = target;
|
||||
|
||||
edgeList->push_back(g);
|
||||
|
@ -40,9 +40,10 @@ template<typename EdgeData, typename GraphT, typename NodeHelperT = NodeInformat
|
||||
class SearchEngine {
|
||||
private:
|
||||
const GraphT * _graph;
|
||||
std::vector<string> * _names;
|
||||
inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;}
|
||||
public:
|
||||
SearchEngine(GraphT * g, NodeHelperT * nh) : _graph(g), nodeHelpDesk(nh) {}
|
||||
SearchEngine(GraphT * g, NodeHelperT * nh, vector<string> * n = new vector<string>()) : _graph(g), nodeHelpDesk(nh), _names(n) {}
|
||||
~SearchEngine() {}
|
||||
|
||||
inline const void getNodeInfo(NodeID id, _Coordinate& result) const
|
||||
@ -56,10 +57,14 @@ public:
|
||||
return nodeHelpDesk->getNumberOfNodes();
|
||||
}
|
||||
|
||||
unsigned int ComputeRoute(PhantomNodes * phantomNodes, vector<std::pair<NodeID, NodeID> > * path, _Coordinate& startCoord, _Coordinate& targetCoord)
|
||||
unsigned int ComputeRoute(PhantomNodes * phantomNodes, vector<NodeID > * path, _Coordinate& startCoord, _Coordinate& targetCoord)
|
||||
{
|
||||
bool onSameEdge = false;
|
||||
bool onSameEdgeReversed = false;
|
||||
bool startReverse = false;
|
||||
bool targetReverse = false;
|
||||
|
||||
|
||||
_Heap * _forwardHeap = new _Heap(nodeHelpDesk->getNumberOfNodes());
|
||||
_Heap * _backwardHeap = new _Heap(nodeHelpDesk->getNumberOfNodes());
|
||||
NodeID middle = ( NodeID ) 0;
|
||||
@ -111,11 +116,10 @@ public:
|
||||
|
||||
} else if(phantomNodes->startNode1 != UINT_MAX)
|
||||
{
|
||||
bool reverse = false;
|
||||
EdgeID edge = _graph->FindEdge( phantomNodes->startNode1, phantomNodes->startNode2);
|
||||
if(edge == UINT_MAX){
|
||||
edge = _graph->FindEdge( phantomNodes->startNode2, phantomNodes->startNode1 );
|
||||
reverse = true;
|
||||
startReverse = true;
|
||||
}
|
||||
if(edge == UINT_MAX){
|
||||
delete _forwardHeap;
|
||||
@ -124,18 +128,17 @@ public:
|
||||
}
|
||||
|
||||
EdgeWeight w = _graph->GetEdgeData( edge ).distance;
|
||||
if( (_graph->GetEdgeData( edge ).backward && !reverse) || (_graph->GetEdgeData( edge ).forward && reverse) )
|
||||
if( (_graph->GetEdgeData( edge ).backward && !startReverse) || (_graph->GetEdgeData( edge ).forward && startReverse) )
|
||||
_forwardHeap->Insert(phantomNodes->startNode1, absDouble( w*phantomNodes->startRatio), phantomNodes->startNode1);
|
||||
if( (_graph->GetEdgeData( edge ).backward && reverse) || (_graph->GetEdgeData( edge ).forward && !reverse) )
|
||||
if( (_graph->GetEdgeData( edge ).backward && startReverse) || (_graph->GetEdgeData( edge ).forward && !startReverse) )
|
||||
_forwardHeap->Insert(phantomNodes->startNode2, absDouble(w-w*phantomNodes->startRatio), phantomNodes->startNode2);
|
||||
}
|
||||
if(phantomNodes->targetNode1 != UINT_MAX && !onSameEdgeReversed)
|
||||
{
|
||||
bool reverse = false;
|
||||
EdgeID edge = _graph->FindEdge( phantomNodes->targetNode1, phantomNodes->targetNode2);
|
||||
if(edge == UINT_MAX){
|
||||
edge = _graph->FindEdge( phantomNodes->targetNode2, phantomNodes->targetNode1 );
|
||||
reverse = true;
|
||||
targetReverse = true;
|
||||
}
|
||||
if(edge == UINT_MAX){
|
||||
delete _forwardHeap;
|
||||
@ -144,9 +147,9 @@ public:
|
||||
}
|
||||
|
||||
EdgeWeight w = _graph->GetEdgeData( edge ).distance;
|
||||
if( (_graph->GetEdgeData( edge ).backward && !reverse) || (_graph->GetEdgeData( edge ).forward && reverse) )
|
||||
if( (_graph->GetEdgeData( edge ).backward && !targetReverse) || (_graph->GetEdgeData( edge ).forward && targetReverse) )
|
||||
_backwardHeap->Insert(phantomNodes->targetNode2, absDouble( w*phantomNodes->targetRatio), phantomNodes->targetNode2);
|
||||
if( (_graph->GetEdgeData( edge ).backward && reverse) || (_graph->GetEdgeData( edge ).forward && !reverse) )
|
||||
if( (_graph->GetEdgeData( edge ).backward && targetReverse) || (_graph->GetEdgeData( edge ).forward && !targetReverse) )
|
||||
_backwardHeap->Insert(phantomNodes->targetNode1, absDouble(w-w*phantomNodes->startRatio), phantomNodes->targetNode1);
|
||||
}
|
||||
|
||||
@ -180,7 +183,7 @@ public:
|
||||
pathNode = _forwardHeap->GetData( pathNode ).parent;
|
||||
packedPath.push_front( pathNode );
|
||||
}
|
||||
|
||||
NodeID realStart = pathNode;
|
||||
packedPath.push_back( middle );
|
||||
pathNode = middle;
|
||||
|
||||
@ -189,12 +192,7 @@ public:
|
||||
packedPath.push_back( pathNode );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// push start node explicitely
|
||||
NodeID nameID = GetNameIDForOriginDestinationNodeID( (phantomNodes->startNode1 == packedPath[0] ? phantomNodes->startNode2 : phantomNodes->startNode1) , packedPath[0]);
|
||||
|
||||
path->push_back(std::make_pair(packedPath[0], nameID) );
|
||||
path->push_back(packedPath[0] );
|
||||
{
|
||||
for(deque<NodeID>::size_type i = 0; i < packedPath.size()-1; i++)
|
||||
{
|
||||
@ -235,7 +233,7 @@ public:
|
||||
|
||||
inline unsigned int findNearestNodeForLatLon(const _Coordinate& coord, _Coordinate& result) const
|
||||
{
|
||||
nodeHelpDesk->findNearestNodeIDForLatLon( coord, result );
|
||||
nodeHelpDesk->findNearestNodeCoordForLatLon( coord, result );
|
||||
}
|
||||
|
||||
inline bool FindRoutingStarts(const _Coordinate start, const _Coordinate target, PhantomNodes * routingStarts)
|
||||
@ -252,6 +250,21 @@ public:
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.middleName.nameID;
|
||||
}
|
||||
|
||||
inline std::string& GetNameForNameID(const NodeID nameID) const {
|
||||
assert(nameID < _names->size());
|
||||
return _names->at(nameID);
|
||||
}
|
||||
|
||||
inline short GetTypeOfEdgeForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
assert(s!=t);
|
||||
EdgeID e = _graph->FindEdge( s, t );
|
||||
if(e == UINT_MAX)
|
||||
e = _graph->FindEdge( t, s );
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.type;
|
||||
}
|
||||
private:
|
||||
NodeHelperT * nodeHelpDesk;
|
||||
|
||||
@ -294,7 +307,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
bool _UnpackEdge( const NodeID source, const NodeID target, std::vector< std::pair<NodeID, NodeID> >* path ) {
|
||||
bool _UnpackEdge( const NodeID source, const NodeID target, std::vector< NodeID >* path ) {
|
||||
assert(source != target);
|
||||
//find edge first.
|
||||
typename GraphT::EdgeIterator smallestEdge = SPECIAL_EDGEID;
|
||||
@ -334,8 +347,7 @@ private:
|
||||
return false;
|
||||
} else {
|
||||
assert(!ed.shortcut);
|
||||
//todo: push nameID along with target as a pair: push_back(std::make_pair(target, nameID))
|
||||
path->push_back(std::make_pair(target, ed.middleName.nameID) );
|
||||
path->push_back(target);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include <string>
|
||||
#include <libxml/xmlreader.h>
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
/* Default Speed Profile:
|
||||
motorway 110
|
||||
motorway_link 90
|
||||
@ -113,13 +115,13 @@ struct Settings {
|
||||
vector< double > speed;
|
||||
vector< string > names;
|
||||
} speedProfile;
|
||||
vector<string> accessList;
|
||||
// vector<string> accessList;
|
||||
int trafficLightPenalty;
|
||||
int indexInAccessListOf( const string & key)
|
||||
{
|
||||
for(int i = 0; i< accessList.size(); i++)
|
||||
for(int i = 0; i< speedProfile.names.size(); i++)
|
||||
{
|
||||
if(accessList[i] == key)
|
||||
if(speedProfile.names[i] == key)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@ -468,6 +470,30 @@ double ApproximateDistance( const int lat1, const int lon1, const int lat2, cons
|
||||
return EARTH_RADIUS_IN_METERS * distanceArc;
|
||||
}
|
||||
|
||||
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
|
||||
double GetAngleBetweenTwoEdges(const _Coordinate& A, const _Coordinate& C, const _Coordinate& B)
|
||||
{
|
||||
// double a = ApproximateDistance(A.lat, A.lon, C.lat, C.lon); //first edge segment
|
||||
// double b = ApproximateDistance(B.lat, B.lon, C.lat, C.lon); //second edge segment
|
||||
// double c = ApproximateDistance(A.lat, A.lon, B.lat, B.lon); //third edgefrom triangle
|
||||
//
|
||||
// double cosAlpha = (a*a + b*b - c*c)/ (2*a*b);
|
||||
//
|
||||
// double alpha = ( (acos(cosAlpha) * 180.0 / M_PI) * (cosAlpha > 0 ? -1 : 1) ) + 180;
|
||||
// return alpha;
|
||||
// V = <x2 - x1, y2 - y1>
|
||||
int v1x = A.lon - C.lon;
|
||||
int v1y = A.lat - C.lat;
|
||||
int v2x = B.lon - C.lon;
|
||||
int v2y = B.lat - C.lat;
|
||||
|
||||
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
|
||||
while(angle < 0)
|
||||
angle += 360;
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
string GetRandomString() {
|
||||
char s[128];
|
||||
static const char alphanum[] =
|
||||
|
@ -44,27 +44,26 @@ public:
|
||||
/** Default constructor. target and weight are set to 0.*/
|
||||
Edge() { assert(false); } //shall not be used.
|
||||
|
||||
explicit Edge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, bool l) : _source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), locatable(l) { }
|
||||
explicit Edge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty) : _source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty) { assert(ty >= 0); }
|
||||
|
||||
NodeID target() const {return _target; }
|
||||
NodeID source() const {return _source; }
|
||||
NodeID name() const { return _name; }
|
||||
EdgeWeight weight() const {return _weight; }
|
||||
|
||||
short type() const { assert(_type >= 0); return _type; }
|
||||
bool isBackward() const { return backward; }
|
||||
|
||||
bool isForward() const { return forward; }
|
||||
|
||||
bool isLocatable() const { return locatable; }
|
||||
bool isLocatable() const { return _type != 14; }
|
||||
|
||||
private:
|
||||
NodeID _source;
|
||||
NodeID _target;
|
||||
NodeID _name;
|
||||
EdgeWeight _weight:29;
|
||||
NodeID _name:31;
|
||||
EdgeWeight _weight:31;
|
||||
bool forward:1;
|
||||
bool backward:1;
|
||||
bool locatable:1;
|
||||
short _type;
|
||||
};
|
||||
|
||||
typedef Edge ImportEdge;
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
|
||||
NodeID getNumberOfNodes() const { return numberOfNodes; }
|
||||
|
||||
inline void findNearestNodeIDForLatLon(const _Coordinate coord, _Coordinate& result) { result = g->FindNearestPointOnEdge(coord); }
|
||||
inline void findNearestNodeCoordForLatLon(const _Coordinate coord, _Coordinate& result) { result = g->FindNearestPointOnEdge(coord); }
|
||||
|
||||
inline bool FindRoutingStarts(const _Coordinate start, const _Coordinate target, PhantomNodes * phantomNodes) {
|
||||
g->FindRoutingStarts(start, target, phantomNodes);
|
||||
|
@ -22,6 +22,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#define TIMEUTIL_H_
|
||||
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <sys/time.h>
|
||||
|
||||
@ -33,4 +34,7 @@ inline double get_timestamp()
|
||||
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
|
||||
}
|
||||
|
||||
double y2lat(double a) { return 180/M_PI * (2 * atan(exp(a*M_PI/180)) - M_PI/2); }
|
||||
double lat2y(double a) { return 180/M_PI * log(tan(M_PI/4+a*(M_PI/180)/2)); }
|
||||
|
||||
#endif /* TIMEUTIL_H_ */
|
||||
|
@ -103,21 +103,11 @@ public:
|
||||
|
||||
_Coordinate startCoord(lat1, lon1);
|
||||
_Coordinate targetCoord(lat2, lon2);
|
||||
// double timestamp2 = get_timestamp();
|
||||
//cout << "coordinates in " << timestamp2 - timestamp << "s" << endl;
|
||||
|
||||
|
||||
vector<std::pair<NodeID, NodeID> > * path = new vector<std::pair<NodeID, NodeID> >();
|
||||
vector<NodeID > * path = new vector<NodeID >();
|
||||
PhantomNodes * phantomNodes = new PhantomNodes();
|
||||
// timestamp = get_timestamp();
|
||||
sEngine->FindRoutingStarts(startCoord, targetCoord, phantomNodes);
|
||||
// timestamp2 = get_timestamp();
|
||||
//cout << "routing starts in " << timestamp2 - timestamp << "s" << endl;
|
||||
// timestamp = get_timestamp();
|
||||
unsigned int distance = sEngine->ComputeRoute(phantomNodes, path, startCoord, targetCoord);
|
||||
// timestamp2 = get_timestamp();
|
||||
//cout << "shortest path in " << timestamp2 - timestamp << "s" << endl;
|
||||
// timestamp = get_timestamp();
|
||||
rep.status = reply::ok;
|
||||
|
||||
string tmp;
|
||||
@ -125,6 +115,11 @@ public:
|
||||
rep.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
rep.content += ("<kml xmlns=\"http://www.opengis.net/kml/2.2\">");
|
||||
rep.content += ("<Document>");
|
||||
|
||||
if(distance != std::numeric_limits<unsigned int>::max())
|
||||
computeDescription(tmp, path, phantomNodes);
|
||||
|
||||
// rep.content += tmp;
|
||||
rep.content += ("<Placemark>");
|
||||
rep.content += ("<name>OSM Routing Engine (c) Dennis Luxen and others </name>");
|
||||
|
||||
@ -145,7 +140,7 @@ public:
|
||||
rep.content += ("<extrude>1</extrude>");
|
||||
rep.content += ("<tessellate>1</tessellate>");
|
||||
rep.content += ("<altitudeMode>absolute</altitudeMode>");
|
||||
rep.content += ("<coordinates>\n");
|
||||
rep.content += ("<coordinates>");
|
||||
|
||||
|
||||
if(distance != std::numeric_limits<unsigned int>::max())
|
||||
@ -156,12 +151,10 @@ public:
|
||||
doubleToString(phantomNodes->startCoord.lat/100000., tmp);
|
||||
rep.content += tmp;
|
||||
rep.content += (" ");
|
||||
|
||||
|
||||
_Coordinate result;
|
||||
for(vector<std::pair<NodeID, NodeID> >::iterator it = path->begin(); it != path->end(); it++)
|
||||
for(vector<NodeID >::iterator it = path->begin(); it != path->end(); it++)
|
||||
{
|
||||
sEngine->getNodeInfo(it->first, result);
|
||||
sEngine->getNodeInfo(*it, result);
|
||||
convertLatLon(result.lon, tmp);
|
||||
rep.content += tmp;
|
||||
rep.content += (",");
|
||||
@ -269,6 +262,121 @@ private:
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void computeDescription(string &tmp, vector<NodeID> * path, PhantomNodes * phantomNodes)
|
||||
{
|
||||
_Coordinate previous(phantomNodes->startCoord.lat, phantomNodes->startCoord.lon);
|
||||
_Coordinate next, current, lastPlace;
|
||||
stringstream numberString;
|
||||
|
||||
double tempDist = 0;
|
||||
NodeID nextID = UINT_MAX;
|
||||
NodeID nameID = sEngine->GetNameIDForOriginDestinationNodeID(phantomNodes->startNode1, phantomNodes->startNode2);
|
||||
short type = sEngine->GetTypeOfEdgeForOriginDestinationNodeID(phantomNodes->startNode1, phantomNodes->startNode2);
|
||||
lastPlace.lat = phantomNodes->startCoord.lat;
|
||||
lastPlace.lon = phantomNodes->startCoord.lon;
|
||||
short nextType = SHRT_MAX;
|
||||
short prevType = SHRT_MAX;
|
||||
tmp += "<Placemark><Name>";
|
||||
for(vector<NodeID >::iterator it = path->begin(); it != path->end(); it++)
|
||||
{
|
||||
sEngine->getNodeInfo(*it, current);
|
||||
if(it==path->end()-1){
|
||||
next = _Coordinate(phantomNodes->targetCoord.lat, phantomNodes->targetCoord.lon);
|
||||
nextID = sEngine->GetNameIDForOriginDestinationNodeID(phantomNodes->targetNode1, phantomNodes->targetNode2);
|
||||
nextType = sEngine->GetTypeOfEdgeForOriginDestinationNodeID(phantomNodes->targetNode1, phantomNodes->targetNode2);
|
||||
} else {
|
||||
sEngine->getNodeInfo(*(it+1), next);
|
||||
nextID = sEngine->GetNameIDForOriginDestinationNodeID(*it, *(it+1));
|
||||
nextType = sEngine->GetTypeOfEdgeForOriginDestinationNodeID(*it, *(it+1));
|
||||
}
|
||||
if(nextID == nameID) {
|
||||
tempDist += ApproximateDistance(previous.lat, previous.lon, current.lat, current.lon);
|
||||
} else {
|
||||
if(type == 0 && prevType != 0)
|
||||
tmp += "enter motorway and ";
|
||||
if(type != 0 && prevType == 0 )
|
||||
tmp += "leave motorway and ";
|
||||
|
||||
double angle = GetAngleBetweenTwoEdges(previous, current, next);
|
||||
tmp += "follow road ";
|
||||
tmp += sEngine->GetNameForNameID(nameID);
|
||||
tmp += " (type: ";
|
||||
numberString << type;
|
||||
tmp += numberString.str();
|
||||
numberString.str("");
|
||||
tmp += ")</Name><Description>drive for ";
|
||||
numberString << ApproximateDistance(previous.lat, previous.lon, current.lat, current.lon)+tempDist;
|
||||
tmp += numberString.str();
|
||||
numberString.str("");
|
||||
tmp += "m </Description>";
|
||||
string lat; string lon;
|
||||
convertLatLon(lastPlace.lon, lon);
|
||||
convertLatLon(lastPlace.lat, lat);
|
||||
lastPlace = current;
|
||||
tmp += "<Point><Coordinates>";
|
||||
tmp += lon;
|
||||
tmp += ",";
|
||||
tmp += lat;
|
||||
tmp += "</Coordinates></Point>";
|
||||
tmp += "</Placemark>";
|
||||
tmp += "<Placemark><Name>";
|
||||
if(angle > 160 && angle < 200) {
|
||||
tmp += /* " (" << angle << ")*/"drive ahead, ";
|
||||
} else if (angle > 290 && angle <= 360) {
|
||||
tmp += /*" (" << angle << ")*/ "turn sharp left, ";
|
||||
} else if (angle > 245 && angle <= 290) {
|
||||
tmp += /*" (" << angle << ")*/ "turn left, ";
|
||||
} else if (angle > 200 && angle <= 245) {
|
||||
tmp += /*" (" << angle << ") */"bear left, ";
|
||||
} else if (angle > 115 && angle <= 160) {
|
||||
tmp += /*" (" << angle << ") */"bear right, ";
|
||||
} else if (angle > 70 && angle <= 115) {
|
||||
tmp += /*" (" << angle << ") */"turn right, ";
|
||||
} else {
|
||||
tmp += /*" (" << angle << ") */"turn sharp right, ";
|
||||
}
|
||||
tempDist = 0;
|
||||
prevType = type;
|
||||
}
|
||||
nameID = nextID;
|
||||
previous = current;
|
||||
type = nextType;
|
||||
}
|
||||
nameID = sEngine->GetNameIDForOriginDestinationNodeID(phantomNodes->targetNode1, phantomNodes->targetNode2);
|
||||
type = sEngine->GetTypeOfEdgeForOriginDestinationNodeID(phantomNodes->targetNode1, phantomNodes->targetNode2);
|
||||
tmp += "follow road ";
|
||||
tmp += sEngine->GetNameForNameID(nameID);
|
||||
tmp += " (type: ";
|
||||
numberString << type;
|
||||
tmp += numberString.str();
|
||||
numberString.str("");
|
||||
tmp += ")</name><Description> drive for ";
|
||||
numberString << (previous.lat, previous.lon, phantomNodes->targetCoord.lat, phantomNodes->targetCoord.lon) + tempDist;
|
||||
tmp += numberString.str();
|
||||
numberString.str("");
|
||||
tmp += "m</Description>";
|
||||
string lat; string lon;
|
||||
convertLatLon(lastPlace.lon, lon);
|
||||
convertLatLon(lastPlace.lat, lat);
|
||||
tmp += "<Point><Coordinates>";
|
||||
tmp += lon;
|
||||
tmp += ",";
|
||||
tmp += lat;
|
||||
tmp += "</Coordinates></Point>";
|
||||
tmp += "</Placemark>";
|
||||
tmp += "<Placemark><Name>you have reached your destination</Name>";
|
||||
tmp += "<Description>End of Route</Description>";
|
||||
convertLatLon(phantomNodes->targetCoord.lon, lon);
|
||||
convertLatLon(phantomNodes->targetCoord.lat, lat);
|
||||
tmp += "<Point><Coordinates>";
|
||||
tmp += lon;
|
||||
tmp += ",";
|
||||
tmp += lat;
|
||||
tmp +="</Coordinates></Point>";
|
||||
tmp += "</Placemark>";
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -156,16 +156,24 @@ int main (int argc, char *argv[])
|
||||
bool shortcut= it->data.shortcut;
|
||||
bool forward= it->data.forward;
|
||||
bool backward= it->data.backward;
|
||||
NodeID middle= it->data.middleName.middle;
|
||||
NodeID middle;
|
||||
if(shortcut)
|
||||
middle = it->data.middleName.middle;
|
||||
else {
|
||||
middle = it->data.middleName.nameID;
|
||||
assert (middle < 10000);
|
||||
}
|
||||
|
||||
NodeID source = it->source;
|
||||
NodeID target = it->target;
|
||||
short type = it->data.type;
|
||||
|
||||
edgeOutFile.write((char *)&(distance), sizeof(int));
|
||||
edgeOutFile.write((char *)&(shortcut), sizeof(bool));
|
||||
edgeOutFile.write((char *)&(forward), sizeof(bool));
|
||||
edgeOutFile.write((char *)&(backward), sizeof(bool));
|
||||
edgeOutFile.write((char *)&(middle), sizeof(NodeID));
|
||||
|
||||
edgeOutFile.write((char *)&(type), sizeof(short));
|
||||
edgeOutFile.write((char *)&(source), sizeof(NodeID));
|
||||
edgeOutFile.write((char *)&(target), sizeof(NodeID));
|
||||
}
|
||||
@ -174,4 +182,5 @@ int main (int argc, char *argv[])
|
||||
|
||||
delete cleanup;
|
||||
delete contractor;
|
||||
cout << "finished" << endl;
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
nodeMap->set_empty_key(UINT_MAX);
|
||||
stringMap->set_empty_key(GetRandomString());
|
||||
stringMap->insert(std::make_pair("", 0));
|
||||
try {
|
||||
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
||||
const int type = xmlTextReaderNodeType( inputReader );
|
||||
@ -100,19 +101,15 @@ int main (int argc, char *argv[])
|
||||
|
||||
if ( way.usefull && way.access && way.path.size() ) {
|
||||
StringMap::iterator strit = stringMap->find(name);
|
||||
if(name == "") {
|
||||
way.nameID = UINT_MAX;
|
||||
} else {
|
||||
if(strit == stringMap->end())
|
||||
{
|
||||
way.nameID = nameVector.size();
|
||||
nameVector.push_back(name);
|
||||
stringMap->insert(std::make_pair(name, way.nameID) );
|
||||
// cout << "found name ID: " << way.nameID << " (" << name << ")" << endl;
|
||||
// cout << "found name ID: " << way.nameID << " (" << name << ")" << endl;
|
||||
} else {
|
||||
way.nameID = strit->second;
|
||||
// cout << "name with ID " << way.nameID << " already existing (" << name << ")" << endl;
|
||||
}
|
||||
// cout << "name with ID " << way.nameID << " already existing (" << name << ")" << endl;
|
||||
}
|
||||
for ( unsigned i = 0; i < way.path.size(); ++i ) {
|
||||
usedNodes.push_back(way.path[i]);
|
||||
@ -269,31 +266,56 @@ int main (int argc, char *argv[])
|
||||
int intWeight = max(1, (int) weight);
|
||||
int intDist = max(1, (int)distance);
|
||||
int ferryIndex = settings.indexInAccessListOf("ferry");
|
||||
assert(ferryIndex != -1);
|
||||
|
||||
//Todo: write nameID and type of edge to osrm
|
||||
switch(eit->direction)
|
||||
{
|
||||
case _Way::notSure:
|
||||
fout << startit->first << " " << targetit->first << " " << intDist << " " << 0 << " " << intWeight << " " << (eit->type == ferryIndex ? false :true ) << "\n";
|
||||
fout << startit->first << " " << targetit->first << " " << intDist << " " << 0 << " " << intWeight << " " << eit->type << " " << eit->nameID << "\n";
|
||||
break;
|
||||
case _Way::oneway:
|
||||
fout << startit->first << " " << targetit->first << " " << intDist << " " << 1 << " " << intWeight << " " << (eit->type == ferryIndex ? false :true ) << "\n";
|
||||
fout << startit->first << " " << targetit->first << " " << intDist << " " << 1 << " " << intWeight << " " << eit->type << " " << eit->nameID << "\n";
|
||||
break;
|
||||
case _Way::bidirectional:
|
||||
fout << startit->first << " " << targetit->first << " " << intDist << " " << 0 << " " << intWeight << " " << (eit->type == ferryIndex ? false :true ) << "\n";
|
||||
fout << startit->first << " " << targetit->first << " " << intDist << " " << 0 << " " << intWeight << " " << eit->type << " " << eit->nameID << "\n";
|
||||
break;
|
||||
case _Way::opposite:
|
||||
fout << startit->first << " " << targetit->first << " " << intDist << " " << 1 << " " << intWeight << " " << (eit->type == ferryIndex ? false :true ) << "\n";
|
||||
fout << startit->first << " " << targetit->first << " " << intDist << " " << 1 << " " << intWeight << " " << eit->type << " " << eit->nameID << "\n";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Todo: serialize list of names
|
||||
|
||||
fout.close();
|
||||
|
||||
name.append(".names");
|
||||
cout << "ok, after " << get_timestamp() - time << "s" << endl;
|
||||
time = get_timestamp();
|
||||
cout << "writing street name index ..." << flush;
|
||||
|
||||
vector<unsigned> * nameIndex = new vector<unsigned>(nameVector.size()+1, 0);
|
||||
unsigned currentNameIndex = 0;
|
||||
for(int i = 0; i < nameVector.size(); i++) {
|
||||
nameIndex->at(i) = currentNameIndex;
|
||||
currentNameIndex += nameVector[i].length();
|
||||
}
|
||||
nameIndex->at(nameVector.size()) = currentNameIndex;
|
||||
ofstream nameOutFile(name.c_str(), ios::binary);
|
||||
unsigned sizeOfNameIndex = nameIndex->size();
|
||||
nameOutFile.write((char *)&(sizeOfNameIndex), sizeof(unsigned));
|
||||
|
||||
for(int i = 0; i < nameIndex->size(); i++) {
|
||||
nameOutFile.write((char *)&(nameIndex->at(i)), sizeof(unsigned));
|
||||
}
|
||||
for(int i = 0; i < nameVector.size(); i++){
|
||||
nameOutFile << nameVector[i];
|
||||
}
|
||||
|
||||
nameOutFile.close();
|
||||
delete nameIndex;
|
||||
cout << "ok, after " << get_timestamp() - time << "s" << endl;
|
||||
|
||||
} catch ( const std::exception& e ) {
|
||||
cerr << "Caught Execption:" << e.what() << endl;
|
||||
return false;
|
||||
|
34
routed.cpp
34
routed.cpp
@ -50,9 +50,9 @@ typedef http::server<StaticGraph<EdgeData> > server;
|
||||
*/
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
if(argc < 4)
|
||||
if(argc < 5)
|
||||
{
|
||||
cerr << "Correct usage:" << endl << argv[0] << " <hsgr data> <nodes data> <ram index> <file index>" << endl;
|
||||
cerr << "Correct usage:" << endl << argv[0] << " <hsgr data> <nodes data> <ram index> <file index> <names data>" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@ -74,11 +74,36 @@ int main (int argc, char *argv[])
|
||||
StaticGraph<EdgeData> * graph = new StaticGraph<EdgeData>(nodeInfoHelper->getNumberOfNodes()-1, *edgeList);
|
||||
delete edgeList;
|
||||
time = get_timestamp();
|
||||
cout << "deserializing street names ..." << flush;
|
||||
ifstream namesInStream(argv[5], ios::binary);
|
||||
unsigned size = 0;
|
||||
namesInStream.read((char *)&size, sizeof(unsigned));
|
||||
vector<unsigned> * nameIndex = new vector<unsigned>(size, 0);
|
||||
vector<string> * names = new vector<string>();
|
||||
// names->push_back("");
|
||||
for(int i = 0; i<size; i++)
|
||||
namesInStream.read((char *)&(nameIndex->at(i)), sizeof(unsigned));
|
||||
|
||||
for(int i = 0; i<size-1; i++){
|
||||
string tempString;
|
||||
for(int j = 0; j < nameIndex->at(i+1) - nameIndex->at(i); j++){
|
||||
char c;
|
||||
namesInStream.read(&c, sizeof(char));
|
||||
tempString.append(1, c);
|
||||
}
|
||||
names->push_back(tempString);
|
||||
tempString = "";
|
||||
}
|
||||
delete nameIndex;
|
||||
|
||||
namesInStream.close();
|
||||
cout << "in " << get_timestamp() - time << "s" << endl;
|
||||
time = get_timestamp();
|
||||
|
||||
cout << "constructing search graph ..." << flush;
|
||||
|
||||
SearchEngine<EdgeData, StaticGraph<EdgeData> > * sEngine = new SearchEngine<EdgeData, StaticGraph<EdgeData> >(graph, nodeInfoHelper);
|
||||
SearchEngine<EdgeData, StaticGraph<EdgeData> > * sEngine = new SearchEngine<EdgeData, StaticGraph<EdgeData> >(graph, nodeInfoHelper, names);
|
||||
cout << "in " << get_timestamp() - time << "s" << endl;
|
||||
|
||||
time = get_timestamp();
|
||||
|
||||
try {
|
||||
@ -115,6 +140,7 @@ int main (int argc, char *argv[])
|
||||
std::cerr << "exception: " << e.what() << "\n";
|
||||
}
|
||||
cout << "graceful shutdown after " << get_timestamp() - time << "s" << endl;
|
||||
delete names;
|
||||
delete sEngine;
|
||||
delete graph;
|
||||
delete nodeInfoHelper;
|
||||
|
Loading…
Reference in New Issue
Block a user