BREAKING CHANGE, REPROCESS YOUR OSM FILES

All preparations necessary to compute and output turn directions.
This commit is contained in:
Dennis Luxen 2010-09-29 15:22:38 +00:00
parent 4c47d5b70e
commit 676f64b0ef
12 changed files with 307 additions and 87 deletions

View File

@ -75,6 +75,7 @@ public:
bool shortcut : 1; bool shortcut : 1;
bool forward : 1; bool forward : 1;
bool backward : 1; bool backward : 1;
short type;
_MiddleName middleName; _MiddleName middleName;
} data; } data;
@ -121,10 +122,10 @@ public:
newEdge.data.distance = _graph[edge].data.distance; newEdge.data.distance = _graph[edge].data.distance;
newEdge.data.shortcut = _graph[edge].data.shortcut; newEdge.data.shortcut = _graph[edge].data.shortcut;
if ( newEdge.data.shortcut ) newEdge.data.middleName = _graph[edge].data.middleName;
newEdge.data.middleName = _graph[edge].data.middleName;
newEdge.data.forward = _graph[edge].data.forward; newEdge.data.forward = _graph[edge].data.forward;
newEdge.data.backward = _graph[edge].data.backward; newEdge.data.backward = _graph[edge].data.backward;
newEdge.data.type = _graph[edge].data.type;
edges.push_back( newEdge ); edges.push_back( newEdge );
} }
#ifdef _GLIBCXX_PARALLEL #ifdef _GLIBCXX_PARALLEL

View File

@ -58,6 +58,7 @@ private:
bool shortcut : 1; bool shortcut : 1;
bool forward : 1; bool forward : 1;
bool backward : 1; bool backward : 1;
short type;
_MiddleName middleName; _MiddleName middleName;
} data; } data;
@ -199,6 +200,7 @@ public:
} }
edge.data.shortcut = false; edge.data.shortcut = false;
edge.data.middleName.nameID = i->name(); edge.data.middleName.nameID = i->name();
edge.data.type = i->type();
edge.data.forward = i->isForward(); edge.data.forward = i->isForward();
edge.data.backward = i->isBackward(); edge.data.backward = i->isBackward();
edge.data.originalEdges = 1; edge.data.originalEdges = 1;
@ -218,6 +220,9 @@ public:
for ( NodeID i = 0; i < edges.size(); ) { for ( NodeID i = 0; i < edges.size(); ) {
const NodeID source = edges[i].source; const NodeID source = edges[i].source;
const NodeID target = edges[i].target; 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 //remove eigenloops
if ( source == target ) { if ( source == target ) {
i++; i++;
@ -229,7 +234,8 @@ public:
forwardEdge.target = backwardEdge.target = target; forwardEdge.target = backwardEdge.target = target;
forwardEdge.data.forward = backwardEdge.data.backward = true; forwardEdge.data.forward = backwardEdge.data.backward = true;
forwardEdge.data.backward = backwardEdge.data.forward = false; 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.shortcut = backwardEdge.data.shortcut = false;
forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1; forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1;
forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max(); forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max();
@ -457,7 +463,15 @@ public:
newEdge.target = target; newEdge.target = target;
newEdge.data.distance = data.distance; newEdge.data.distance = data.distance;
newEdge.data.shortcut = data.shortcut; newEdge.data.shortcut = data.shortcut;
newEdge.data.middleName.middle = data.middleName.middle; 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.forward = data.forward;
newEdge.data.backward = data.backward; newEdge.data.backward = data.backward;
edges.push_back( newEdge ); edges.push_back( newEdge );
@ -546,9 +560,6 @@ private:
assert(false); assert(false);
return 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 ) { template< bool Simulate > bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) {
_Heap& heap = data->heap; _Heap& heap = data->heap;
//std::vector< Witness >& witnessList = data->witnessList;
for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) { for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) {
const _EdgeData& inData = _graph->GetEdgeData( inEdge ); const _EdgeData& inData = _graph->GetEdgeData( inEdge );

View File

@ -45,7 +45,7 @@ template<typename EdgeT>
NodeID readOSRMGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<NodeInfo> * int2ExtNodeMap) { NodeID readOSRMGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<NodeInfo> * int2ExtNodeMap) {
NodeID n, source, target, id; NodeID n, source, target, id;
EdgeID m; EdgeID m;
bool locatable; short locatable;
int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open) int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open)
ExternalNodeMap ext2IntNodeMap; ExternalNodeMap ext2IntNodeMap;
ext2IntNodeMap.set_empty_key(UINT_MAX); ext2IntNodeMap.set_empty_key(UINT_MAX);
@ -62,9 +62,10 @@ NodeID readOSRMGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<Node
edgeList.reserve(m); edgeList.reserve(m);
for (EdgeID i=0; i<m; i++) { for (EdgeID i=0; i<m; i++) {
EdgeWeight weight; EdgeWeight weight;
short type;
NodeID nameID;
int length; int length;
in >> source >> target >> length >> dir >> weight >> locatable; in >> source >> target >> length >> dir >> weight >> type >> nameID;
assert(length > 0); assert(length > 0);
assert(weight > 0); assert(weight > 0);
assert(0<=dir && dir<=2); 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); } 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); edgeList.push_back(inputEdge);
} }
ext2IntNodeMap.clear(); ext2IntNodeMap.clear();
@ -112,6 +113,7 @@ void readHSGRFromStream(istream &in, vector<EdgeT> * edgeList) {
bool shortcut; bool shortcut;
bool forward; bool forward;
bool backward; bool backward;
short type;
NodeID middle; NodeID middle;
NodeID source; NodeID source;
NodeID target; NodeID target;
@ -122,9 +124,10 @@ void readHSGRFromStream(istream &in, vector<EdgeT> * edgeList) {
in.read((char *)&(forward), sizeof(bool)); in.read((char *)&(forward), sizeof(bool));
in.read((char *)&(backward), sizeof(bool)); in.read((char *)&(backward), sizeof(bool));
in.read((char *)&(middle), sizeof(NodeID)); in.read((char *)&(middle), sizeof(NodeID));
in.read((char *)&(type), sizeof(short));
in.read((char *)&(source), sizeof(NodeID)); in.read((char *)&(source), sizeof(NodeID));
in.read((char *)&(target), 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; g.data = e; g.source = source; g.target = target;
edgeList->push_back(g); edgeList->push_back(g);

View File

@ -40,9 +40,10 @@ template<typename EdgeData, typename GraphT, typename NodeHelperT = NodeInformat
class SearchEngine { class SearchEngine {
private: private:
const GraphT * _graph; const GraphT * _graph;
std::vector<string> * _names;
inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;} inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;}
public: 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() {} ~SearchEngine() {}
inline const void getNodeInfo(NodeID id, _Coordinate& result) const inline const void getNodeInfo(NodeID id, _Coordinate& result) const
@ -56,10 +57,14 @@ public:
return nodeHelpDesk->getNumberOfNodes(); 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 onSameEdge = false;
bool onSameEdgeReversed = false; bool onSameEdgeReversed = false;
bool startReverse = false;
bool targetReverse = false;
_Heap * _forwardHeap = new _Heap(nodeHelpDesk->getNumberOfNodes()); _Heap * _forwardHeap = new _Heap(nodeHelpDesk->getNumberOfNodes());
_Heap * _backwardHeap = new _Heap(nodeHelpDesk->getNumberOfNodes()); _Heap * _backwardHeap = new _Heap(nodeHelpDesk->getNumberOfNodes());
NodeID middle = ( NodeID ) 0; NodeID middle = ( NodeID ) 0;
@ -111,11 +116,10 @@ public:
} else if(phantomNodes->startNode1 != UINT_MAX) } else if(phantomNodes->startNode1 != UINT_MAX)
{ {
bool reverse = false;
EdgeID edge = _graph->FindEdge( phantomNodes->startNode1, phantomNodes->startNode2); EdgeID edge = _graph->FindEdge( phantomNodes->startNode1, phantomNodes->startNode2);
if(edge == UINT_MAX){ if(edge == UINT_MAX){
edge = _graph->FindEdge( phantomNodes->startNode2, phantomNodes->startNode1 ); edge = _graph->FindEdge( phantomNodes->startNode2, phantomNodes->startNode1 );
reverse = true; startReverse = true;
} }
if(edge == UINT_MAX){ if(edge == UINT_MAX){
delete _forwardHeap; delete _forwardHeap;
@ -124,18 +128,17 @@ public:
} }
EdgeWeight w = _graph->GetEdgeData( edge ).distance; 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); _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); _forwardHeap->Insert(phantomNodes->startNode2, absDouble(w-w*phantomNodes->startRatio), phantomNodes->startNode2);
} }
if(phantomNodes->targetNode1 != UINT_MAX && !onSameEdgeReversed) if(phantomNodes->targetNode1 != UINT_MAX && !onSameEdgeReversed)
{ {
bool reverse = false;
EdgeID edge = _graph->FindEdge( phantomNodes->targetNode1, phantomNodes->targetNode2); EdgeID edge = _graph->FindEdge( phantomNodes->targetNode1, phantomNodes->targetNode2);
if(edge == UINT_MAX){ if(edge == UINT_MAX){
edge = _graph->FindEdge( phantomNodes->targetNode2, phantomNodes->targetNode1 ); edge = _graph->FindEdge( phantomNodes->targetNode2, phantomNodes->targetNode1 );
reverse = true; targetReverse = true;
} }
if(edge == UINT_MAX){ if(edge == UINT_MAX){
delete _forwardHeap; delete _forwardHeap;
@ -144,9 +147,9 @@ public:
} }
EdgeWeight w = _graph->GetEdgeData( edge ).distance; 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); _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); _backwardHeap->Insert(phantomNodes->targetNode1, absDouble(w-w*phantomNodes->startRatio), phantomNodes->targetNode1);
} }
@ -180,7 +183,7 @@ public:
pathNode = _forwardHeap->GetData( pathNode ).parent; pathNode = _forwardHeap->GetData( pathNode ).parent;
packedPath.push_front( pathNode ); packedPath.push_front( pathNode );
} }
NodeID realStart = pathNode;
packedPath.push_back( middle ); packedPath.push_back( middle );
pathNode = middle; pathNode = middle;
@ -189,12 +192,7 @@ public:
packedPath.push_back( pathNode ); packedPath.push_back( pathNode );
} }
path->push_back(packedPath[0] );
// 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) );
{ {
for(deque<NodeID>::size_type i = 0; i < packedPath.size()-1; i++) 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 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) inline bool FindRoutingStarts(const _Coordinate start, const _Coordinate target, PhantomNodes * routingStarts)
@ -252,6 +250,21 @@ public:
const EdgeData ed = _graph->GetEdgeData(e); const EdgeData ed = _graph->GetEdgeData(e);
return ed.middleName.nameID; 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: private:
NodeHelperT * nodeHelpDesk; 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); assert(source != target);
//find edge first. //find edge first.
typename GraphT::EdgeIterator smallestEdge = SPECIAL_EDGEID; typename GraphT::EdgeIterator smallestEdge = SPECIAL_EDGEID;
@ -334,8 +347,7 @@ private:
return false; return false;
} else { } else {
assert(!ed.shortcut); assert(!ed.shortcut);
//todo: push nameID along with target as a pair: push_back(std::make_pair(target, nameID)) path->push_back(target);
path->push_back(std::make_pair(target, ed.middleName.nameID) );
return true; return true;
} }
} }

View File

@ -26,6 +26,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <string> #include <string>
#include <libxml/xmlreader.h> #include <libxml/xmlreader.h>
#include "Util.h"
/* Default Speed Profile: /* Default Speed Profile:
motorway 110 motorway 110
motorway_link 90 motorway_link 90
@ -113,13 +115,13 @@ struct Settings {
vector< double > speed; vector< double > speed;
vector< string > names; vector< string > names;
} speedProfile; } speedProfile;
vector<string> accessList; // vector<string> accessList;
int trafficLightPenalty; int trafficLightPenalty;
int indexInAccessListOf( const string & key) 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 i;
} }
return -1; return -1;
@ -468,6 +470,30 @@ double ApproximateDistance( const int lat1, const int lon1, const int lat2, cons
return EARTH_RADIUS_IN_METERS * distanceArc; 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() { string GetRandomString() {
char s[128]; char s[128];
static const char alphanum[] = static const char alphanum[] =

View File

@ -44,27 +44,26 @@ public:
/** Default constructor. target and weight are set to 0.*/ /** Default constructor. target and weight are set to 0.*/
Edge() { assert(false); } //shall not be used. 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 target() const {return _target; }
NodeID source() const {return _source; } NodeID source() const {return _source; }
NodeID name() const { return _name; } NodeID name() const { return _name; }
EdgeWeight weight() const {return _weight; } EdgeWeight weight() const {return _weight; }
short type() const { assert(_type >= 0); return _type; }
bool isBackward() const { return backward; } bool isBackward() const { return backward; }
bool isForward() const { return forward; } bool isForward() const { return forward; }
bool isLocatable() const { return _type != 14; }
bool isLocatable() const { return locatable; }
private: private:
NodeID _source; NodeID _source;
NodeID _target; NodeID _target;
NodeID _name; NodeID _name:31;
EdgeWeight _weight:29; EdgeWeight _weight:31;
bool forward:1; bool forward:1;
bool backward:1; bool backward:1;
bool locatable:1; short _type;
}; };
typedef Edge ImportEdge; typedef Edge ImportEdge;

View File

@ -54,7 +54,7 @@ public:
NodeID getNumberOfNodes() const { return numberOfNodes; } 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) { inline bool FindRoutingStarts(const _Coordinate start, const _Coordinate target, PhantomNodes * phantomNodes) {
g->FindRoutingStarts(start, target, phantomNodes); g->FindRoutingStarts(start, target, phantomNodes);

View File

@ -22,6 +22,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define TIMEUTIL_H_ #define TIMEUTIL_H_
#include <climits> #include <climits>
#include <cmath>
#include <cstdlib> #include <cstdlib>
#include <sys/time.h> #include <sys/time.h>
@ -33,4 +34,7 @@ inline double get_timestamp()
return double(tp.tv_sec) + tp.tv_usec / 1000000.; 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_ */ #endif /* TIMEUTIL_H_ */

View File

@ -103,21 +103,11 @@ public:
_Coordinate startCoord(lat1, lon1); _Coordinate startCoord(lat1, lon1);
_Coordinate targetCoord(lat2, lon2); _Coordinate targetCoord(lat2, lon2);
// double timestamp2 = get_timestamp();
//cout << "coordinates in " << timestamp2 - timestamp << "s" << endl;
vector<NodeID > * path = new vector<NodeID >();
vector<std::pair<NodeID, NodeID> > * path = new vector<std::pair<NodeID, NodeID> >();
PhantomNodes * phantomNodes = new PhantomNodes(); PhantomNodes * phantomNodes = new PhantomNodes();
// timestamp = get_timestamp();
sEngine->FindRoutingStarts(startCoord, targetCoord, phantomNodes); 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); 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; rep.status = reply::ok;
string tmp; string tmp;
@ -125,6 +115,11 @@ public:
rep.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); rep.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
rep.content += ("<kml xmlns=\"http://www.opengis.net/kml/2.2\">"); rep.content += ("<kml xmlns=\"http://www.opengis.net/kml/2.2\">");
rep.content += ("<Document>"); rep.content += ("<Document>");
if(distance != std::numeric_limits<unsigned int>::max())
computeDescription(tmp, path, phantomNodes);
// rep.content += tmp;
rep.content += ("<Placemark>"); rep.content += ("<Placemark>");
rep.content += ("<name>OSM Routing Engine (c) Dennis Luxen and others </name>"); rep.content += ("<name>OSM Routing Engine (c) Dennis Luxen and others </name>");
@ -145,7 +140,7 @@ public:
rep.content += ("<extrude>1</extrude>"); rep.content += ("<extrude>1</extrude>");
rep.content += ("<tessellate>1</tessellate>"); rep.content += ("<tessellate>1</tessellate>");
rep.content += ("<altitudeMode>absolute</altitudeMode>"); rep.content += ("<altitudeMode>absolute</altitudeMode>");
rep.content += ("<coordinates>\n"); rep.content += ("<coordinates>");
if(distance != std::numeric_limits<unsigned int>::max()) if(distance != std::numeric_limits<unsigned int>::max())
@ -156,12 +151,10 @@ public:
doubleToString(phantomNodes->startCoord.lat/100000., tmp); doubleToString(phantomNodes->startCoord.lat/100000., tmp);
rep.content += tmp; rep.content += tmp;
rep.content += (" "); rep.content += (" ");
_Coordinate result; _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); convertLatLon(result.lon, tmp);
rep.content += tmp; rep.content += tmp;
rep.content += (","); rep.content += (",");
@ -269,6 +262,121 @@ private:
} }
return buffer; 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>";
}
}; };
} }

View File

@ -156,16 +156,24 @@ int main (int argc, char *argv[])
bool shortcut= it->data.shortcut; bool shortcut= it->data.shortcut;
bool forward= it->data.forward; bool forward= it->data.forward;
bool backward= it->data.backward; 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 source = it->source;
NodeID target = it->target; NodeID target = it->target;
short type = it->data.type;
edgeOutFile.write((char *)&(distance), sizeof(int)); edgeOutFile.write((char *)&(distance), sizeof(int));
edgeOutFile.write((char *)&(shortcut), sizeof(bool)); edgeOutFile.write((char *)&(shortcut), sizeof(bool));
edgeOutFile.write((char *)&(forward), sizeof(bool)); edgeOutFile.write((char *)&(forward), sizeof(bool));
edgeOutFile.write((char *)&(backward), sizeof(bool)); edgeOutFile.write((char *)&(backward), sizeof(bool));
edgeOutFile.write((char *)&(middle), sizeof(NodeID)); edgeOutFile.write((char *)&(middle), sizeof(NodeID));
edgeOutFile.write((char *)&(type), sizeof(short));
edgeOutFile.write((char *)&(source), sizeof(NodeID)); edgeOutFile.write((char *)&(source), sizeof(NodeID));
edgeOutFile.write((char *)&(target), sizeof(NodeID)); edgeOutFile.write((char *)&(target), sizeof(NodeID));
} }
@ -174,4 +182,5 @@ int main (int argc, char *argv[])
delete cleanup; delete cleanup;
delete contractor; delete contractor;
cout << "finished" << endl;
} }

View File

@ -75,7 +75,8 @@ int main (int argc, char *argv[])
nodeMap->set_empty_key(UINT_MAX); nodeMap->set_empty_key(UINT_MAX);
stringMap->set_empty_key(GetRandomString()); stringMap->set_empty_key(GetRandomString());
try { stringMap->insert(std::make_pair("", 0));
try {
while ( xmlTextReaderRead( inputReader ) == 1 ) { while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int type = xmlTextReaderNodeType( inputReader ); const int type = xmlTextReaderNodeType( inputReader );
@ -100,19 +101,15 @@ int main (int argc, char *argv[])
if ( way.usefull && way.access && way.path.size() ) { if ( way.usefull && way.access && way.path.size() ) {
StringMap::iterator strit = stringMap->find(name); StringMap::iterator strit = stringMap->find(name);
if(name == "") { if(strit == stringMap->end())
way.nameID = UINT_MAX; {
way.nameID = nameVector.size();
nameVector.push_back(name);
stringMap->insert(std::make_pair(name, way.nameID) );
// cout << "found name ID: " << way.nameID << " (" << name << ")" << endl;
} else { } else {
if(strit == stringMap->end()) way.nameID = strit->second;
{ // cout << "name with ID " << way.nameID << " already existing (" << name << ")" << endl;
way.nameID = nameVector.size();
nameVector.push_back(name);
stringMap->insert(std::make_pair(name, way.nameID) );
// cout << "found name ID: " << way.nameID << " (" << name << ")" << endl;
} else {
way.nameID = strit->second;
// cout << "name with ID " << way.nameID << " already existing (" << name << ")" << endl;
}
} }
for ( unsigned i = 0; i < way.path.size(); ++i ) { for ( unsigned i = 0; i < way.path.size(); ++i ) {
usedNodes.push_back(way.path[i]); usedNodes.push_back(way.path[i]);
@ -269,31 +266,56 @@ int main (int argc, char *argv[])
int intWeight = max(1, (int) weight); int intWeight = max(1, (int) weight);
int intDist = max(1, (int)distance); int intDist = max(1, (int)distance);
int ferryIndex = settings.indexInAccessListOf("ferry"); int ferryIndex = settings.indexInAccessListOf("ferry");
assert(ferryIndex != -1);
//Todo: write nameID and type of edge to osrm
switch(eit->direction) switch(eit->direction)
{ {
case _Way::notSure: 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; break;
case _Way::oneway: 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; break;
case _Way::bidirectional: 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; break;
case _Way::opposite: 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; break;
default: default:
assert(false); assert(false);
break; break;
} }
} }
//Todo: serialize list of names
fout.close(); fout.close();
name.append(".names");
cout << "ok, after " << get_timestamp() - time << "s" << endl; 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 ) { } catch ( const std::exception& e ) {
cerr << "Caught Execption:" << e.what() << endl; cerr << "Caught Execption:" << e.what() << endl;
return false; return false;

View File

@ -50,9 +50,9 @@ typedef http::server<StaticGraph<EdgeData> > server;
*/ */
int main (int argc, char *argv[]) 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); exit(-1);
} }
@ -74,11 +74,36 @@ int main (int argc, char *argv[])
StaticGraph<EdgeData> * graph = new StaticGraph<EdgeData>(nodeInfoHelper->getNumberOfNodes()-1, *edgeList); StaticGraph<EdgeData> * graph = new StaticGraph<EdgeData>(nodeInfoHelper->getNumberOfNodes()-1, *edgeList);
delete edgeList; delete edgeList;
time = get_timestamp(); 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; 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; cout << "in " << get_timestamp() - time << "s" << endl;
time = get_timestamp(); time = get_timestamp();
try { try {
@ -115,6 +140,7 @@ int main (int argc, char *argv[])
std::cerr << "exception: " << e.what() << "\n"; std::cerr << "exception: " << e.what() << "\n";
} }
cout << "graceful shutdown after " << get_timestamp() - time << "s" << endl; cout << "graceful shutdown after " << get_timestamp() - time << "s" << endl;
delete names;
delete sEngine; delete sEngine;
delete graph; delete graph;
delete nodeInfoHelper; delete nodeInfoHelper;