Moved descriptors into their own folder.
This commit is contained in:
		
							parent
							
								
									95bcfa3dce
								
							
						
					
					
						commit
						14c999fc82
					
				| @ -24,13 +24,14 @@ or see http://www.gnu.org/licenses/agpl.txt. | |||||||
| #include <climits> | #include <climits> | ||||||
| #include <string> | #include <string> | ||||||
| #include <boost/unordered_map.hpp> | #include <boost/unordered_map.hpp> | ||||||
|  | #include "../typedefs.h" | ||||||
| #include "Util.h" | #include "Util.h" | ||||||
| 
 | 
 | ||||||
| struct _PathData { | struct _PathData { | ||||||
|     _PathData(NodeID no, unsigned na, unsigned tu, unsigned le) : node(no), nameID(na), lengthOfSegment(le), turnInstruction(tu) { } |     _PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { } | ||||||
|     NodeID node; |     NodeID node; | ||||||
|     unsigned nameID; |     unsigned nameID; | ||||||
|     unsigned lengthOfSegment; |     unsigned durationOfSegment; | ||||||
|     short turnInstruction; |     short turnInstruction; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -32,28 +32,28 @@ or see http://www.gnu.org/licenses/agpl.txt. | |||||||
| #include "../typedefs.h" | #include "../typedefs.h" | ||||||
| 
 | 
 | ||||||
| struct _HeapData { | struct _HeapData { | ||||||
| 	NodeID parent; |     NodeID parent; | ||||||
| 	_HeapData( NodeID p ) : parent(p) { } |     _HeapData( NodeID p ) : parent(p) { } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct _Statistics { | struct _Statistics { | ||||||
| 	_Statistics () : insertedNodes(0), stalledNodes(0), meetingNodes(0), deleteMins(0), decreasedNodes(0), oqf(0), eqf(0), df(0), preprocTime(0) {}; |     _Statistics () : insertedNodes(0), stalledNodes(0), meetingNodes(0), deleteMins(0), decreasedNodes(0), oqf(0), eqf(0), df(0), preprocTime(0) {}; | ||||||
| 	void Reset() { |     void Reset() { | ||||||
| 		insertedNodes = 0; |         insertedNodes = 0; | ||||||
| 		stalledNodes = 0; |         stalledNodes = 0; | ||||||
| 		meetingNodes = 0; |         meetingNodes = 0; | ||||||
| 		deleteMins = 0; |         deleteMins = 0; | ||||||
| 		decreasedNodes = 0; |         decreasedNodes = 0; | ||||||
| 	} |     } | ||||||
| 	unsigned insertedNodes; |     unsigned insertedNodes; | ||||||
| 	unsigned stalledNodes; |     unsigned stalledNodes; | ||||||
| 	unsigned meetingNodes; |     unsigned meetingNodes; | ||||||
| 	unsigned deleteMins; |     unsigned deleteMins; | ||||||
| 	unsigned decreasedNodes; |     unsigned decreasedNodes; | ||||||
| 	unsigned oqf; |     unsigned oqf; | ||||||
| 	unsigned eqf; |     unsigned eqf; | ||||||
| 	unsigned df; |     unsigned df; | ||||||
| 	double preprocTime; |     double preprocTime; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef boost::thread_specific_ptr<BinaryHeap< NodeID, NodeID, int, _HeapData > > HeapPtr; | typedef boost::thread_specific_ptr<BinaryHeap< NodeID, NodeID, int, _HeapData > > HeapPtr; | ||||||
| @ -63,18 +63,18 @@ class SearchEngine { | |||||||
| private: | private: | ||||||
|     const GraphT * _graph; |     const GraphT * _graph; | ||||||
|     NodeInformationHelpDesk * nodeHelpDesk; |     NodeInformationHelpDesk * nodeHelpDesk; | ||||||
| 	std::vector<string> * _names; |     std::vector<string> * _names; | ||||||
| 	static HeapPtr _forwardHeap; |     static HeapPtr _forwardHeap; | ||||||
| 	static HeapPtr _backwardHeap; |     static HeapPtr _backwardHeap; | ||||||
| 	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, NodeInformationHelpDesk * nh, vector<string> * n = new vector<string>()) : _graph(g), nodeHelpDesk(nh), _names(n) {} |     SearchEngine(GraphT * g, NodeInformationHelpDesk * nh, vector<string> * n = new vector<string>()) : _graph(g), nodeHelpDesk(nh), _names(n) {} | ||||||
| 	~SearchEngine() {} |     ~SearchEngine() {} | ||||||
| 
 | 
 | ||||||
| 	inline const void GetCoordinatesForNodeID(NodeID id, _Coordinate& result) const { |     inline const void GetCoordinatesForNodeID(NodeID id, _Coordinate& result) const { | ||||||
| 		result.lat = nodeHelpDesk->getLatitudeOfNode(id); |         result.lat = nodeHelpDesk->getLatitudeOfNode(id); | ||||||
| 		result.lon = nodeHelpDesk->getLongitudeOfNode(id); |         result.lon = nodeHelpDesk->getLongitudeOfNode(id); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
|     inline void InitializeThreadLocalStorageIfNecessary() { |     inline void InitializeThreadLocalStorageIfNecessary() { | ||||||
|         if(!_forwardHeap.get()) |         if(!_forwardHeap.get()) | ||||||
| @ -98,22 +98,23 @@ public: | |||||||
|         if(phantomNodes.PhantomsAreOnSameNodeBasedEdge()){ |         if(phantomNodes.PhantomsAreOnSameNodeBasedEdge()){ | ||||||
|             //TODO: Hier behandeln, dass Start und Ziel auf der gleichen Originalkante liegen
 |             //TODO: Hier behandeln, dass Start und Ziel auf der gleichen Originalkante liegen
 | ||||||
|             INFO("TODO: Start and target are on same edge") |             INFO("TODO: Start and target are on same edge") | ||||||
|             return _upperbound; |                                     return _upperbound; | ||||||
|         } |         } | ||||||
|  |         double time1 = get_timestamp(); | ||||||
|         //insert start and/or target node of start edge
 |         //insert start and/or target node of start edge
 | ||||||
|         _forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode, -phantomNodes.startPhantom.weight1, phantomNodes.startPhantom.edgeBasedNode); |         _forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode, -phantomNodes.startPhantom.weight1, phantomNodes.startPhantom.edgeBasedNode); | ||||||
| //        INFO("[FORW] Inserting node " << phantomNodes.startPhantom.edgeBasedNode << " at distance " << -phantomNodes.startPhantom.weight1);
 |         //        INFO("[FORW] Inserting node " << phantomNodes.startPhantom.edgeBasedNode << " at distance " << -phantomNodes.startPhantom.weight1);
 | ||||||
|         if(phantomNodes.startPhantom.isBidirected) { |         if(phantomNodes.startPhantom.isBidirected) { | ||||||
|             _forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode+1, -phantomNodes.startPhantom.weight2, phantomNodes.startPhantom.edgeBasedNode+1); |             _forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode+1, -phantomNodes.startPhantom.weight2, phantomNodes.startPhantom.edgeBasedNode+1); | ||||||
| //            INFO("[FORW] Inserting node " << phantomNodes.startPhantom.edgeBasedNode+1 << " at distance " << -phantomNodes.startPhantom.weight2);
 |             //            INFO("[FORW] Inserting node " << phantomNodes.startPhantom.edgeBasedNode+1 << " at distance " << -phantomNodes.startPhantom.weight2);
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         //insert start and/or target node of target edge id
 |         //insert start and/or target node of target edge id
 | ||||||
|         _backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode, -phantomNodes.targetPhantom.weight1, phantomNodes.targetPhantom.edgeBasedNode); |         _backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode, -phantomNodes.targetPhantom.weight1, phantomNodes.targetPhantom.edgeBasedNode); | ||||||
| //        INFO("[BACK] Inserting node " << phantomNodes.targetPhantom.edgeBasedNode << " at distance " << -phantomNodes.targetPhantom.weight1);
 |         //        INFO("[BACK] Inserting node " << phantomNodes.targetPhantom.edgeBasedNode << " at distance " << -phantomNodes.targetPhantom.weight1);
 | ||||||
|         if(phantomNodes.targetPhantom.isBidirected) { |         if(phantomNodes.targetPhantom.isBidirected) { | ||||||
|             _backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode+1, -phantomNodes.targetPhantom.weight2, phantomNodes.targetPhantom.edgeBasedNode+1); |             _backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode+1, -phantomNodes.targetPhantom.weight2, phantomNodes.targetPhantom.edgeBasedNode+1); | ||||||
| //            INFO("[BACK] Inserting node " << phantomNodes.targetPhantom.edgeBasedNode+1 << " at distance " << -phantomNodes.targetPhantom.weight2);
 |             //            INFO("[BACK] Inserting node " << phantomNodes.targetPhantom.edgeBasedNode+1 << " at distance " << -phantomNodes.targetPhantom.weight2);
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         while(_forwardHeap->Size() + _backwardHeap->Size() > 0){ |         while(_forwardHeap->Size() + _backwardHeap->Size() > 0){ | ||||||
| @ -124,28 +125,31 @@ public: | |||||||
|                 _RoutingStep(_backwardHeap, _forwardHeap, false, &middle, &_upperbound); |                 _RoutingStep(_backwardHeap, _forwardHeap, false, &middle, &_upperbound); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| //        INFO("bidirectional search iteration ended: " << _forwardHeap->Size() << "," << _backwardHeap->Size() << ", dist: " << _upperbound);
 |         //        INFO("bidirectional search iteration ended: " << _forwardHeap->Size() << "," << _backwardHeap->Size() << ", dist: " << _upperbound);
 | ||||||
| 
 |         double time2 = get_timestamp(); | ||||||
|         if ( _upperbound == INT_MAX ) { |         if ( _upperbound == INT_MAX ) { | ||||||
| 			return _upperbound; |             return _upperbound; | ||||||
| 		} |         } | ||||||
|         NodeID pathNode = middle; |         NodeID pathNode = middle; | ||||||
|         deque<NodeID> packedPath; |         deque<NodeID> packedPath; | ||||||
|         while(phantomNodes.startPhantom.edgeBasedNode != pathNode && (!phantomNodes.startPhantom.isBidirected || phantomNodes.startPhantom.edgeBasedNode+1 != pathNode) ) { |         while(phantomNodes.startPhantom.edgeBasedNode != pathNode && (!phantomNodes.startPhantom.isBidirected || phantomNodes.startPhantom.edgeBasedNode+1 != pathNode) ) { | ||||||
|             pathNode = _forwardHeap->GetData(pathNode).parent; |             pathNode = _forwardHeap->GetData(pathNode).parent; | ||||||
|             packedPath.push_front(pathNode); |             packedPath.push_front(pathNode); | ||||||
|         } |         } | ||||||
| //        INFO("Finished getting packed forward path: " << packedPath.size());
 |         //        INFO("Finished getting packed forward path: " << packedPath.size());
 | ||||||
|         packedPath.push_back(middle); |         packedPath.push_back(middle); | ||||||
|         pathNode = middle; |         pathNode = middle; | ||||||
|         while(phantomNodes.targetPhantom.edgeBasedNode != pathNode && (!phantomNodes.targetPhantom.isBidirected || phantomNodes.targetPhantom.edgeBasedNode+1 != pathNode)) { |         while(phantomNodes.targetPhantom.edgeBasedNode != pathNode && (!phantomNodes.targetPhantom.isBidirected || phantomNodes.targetPhantom.edgeBasedNode+1 != pathNode)) { | ||||||
|             pathNode = _backwardHeap->GetData(pathNode).parent; |             pathNode = _backwardHeap->GetData(pathNode).parent; | ||||||
|             packedPath.push_back(pathNode); |             packedPath.push_back(pathNode); | ||||||
|         } |         } | ||||||
| //        INFO("Finished getting packed path: " << packedPath.size());
 |         //        INFO("Finished getting packed path: " << packedPath.size());
 | ||||||
|         for(deque<NodeID>::size_type i = 0;i < packedPath.size() - 1;i++){ |         for(deque<NodeID>::size_type i = 0;i < packedPath.size() - 1;i++){ | ||||||
|             _UnpackEdge(packedPath[i], packedPath[i + 1], path); |             _UnpackEdge(packedPath[i], packedPath[i + 1], path); | ||||||
|         } |         } | ||||||
|  |         double time3 = get_timestamp(); | ||||||
|  |         INFO("Path computed in " << (time2-time1)*1000 << "msec, unpacked in " << (time3-time2)*1000 << "msec"); | ||||||
|  | 
 | ||||||
|         return _upperbound; |         return _upperbound; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -200,10 +204,10 @@ public: | |||||||
| 
 | 
 | ||||||
|         EdgeID e = _graph->FindEdge(s, t); |         EdgeID e = _graph->FindEdge(s, t); | ||||||
|         if(e == UINT_MAX) |         if(e == UINT_MAX) | ||||||
| 			e = _graph->FindEdge( t, s ); |             e = _graph->FindEdge( t, s ); | ||||||
|         if(UINT_MAX == e) { |         if(UINT_MAX == e) { | ||||||
| 			return 0; |             return 0; | ||||||
| 		} |         } | ||||||
|         assert(e != UINT_MAX); |         assert(e != UINT_MAX); | ||||||
|         const EdgeData ed = _graph->GetEdgeData(e); |         const EdgeData ed = _graph->GetEdgeData(e); | ||||||
|         return ed.via; |         return ed.via; | ||||||
| @ -222,7 +226,7 @@ private: | |||||||
|     inline void _RoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, int *_upperbound) { |     inline void _RoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, int *_upperbound) { | ||||||
|         const NodeID node = _forwardHeap->DeleteMin(); |         const NodeID node = _forwardHeap->DeleteMin(); | ||||||
|         const int distance = _forwardHeap->GetKey(node); |         const int distance = _forwardHeap->GetKey(node); | ||||||
| //        INFO((forwardDirection ? "[FORW]" : "[BACK]") << " settling " << node << " with distance " << distance);
 |         //        INFO((forwardDirection ? "[FORW]" : "[BACK]") << " settling " << node << " with distance " << distance);
 | ||||||
|         if(_backwardHeap->WasInserted(node)){ |         if(_backwardHeap->WasInserted(node)){ | ||||||
|             const int newDistance = _backwardHeap->GetKey(node) + distance; |             const int newDistance = _backwardHeap->GetKey(node) + distance; | ||||||
|             if(newDistance < *_upperbound){ |             if(newDistance < *_upperbound){ | ||||||
| @ -235,46 +239,48 @@ private: | |||||||
|             _forwardHeap->DeleteAll(); |             _forwardHeap->DeleteAll(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) { |  | ||||||
| 			const NodeID to = _graph->GetTarget(edge); |  | ||||||
| 			const int edgeWeight = _graph->GetEdgeData(edge).distance; |  | ||||||
| 
 |  | ||||||
| 			assert( edgeWeight > 0 ); |  | ||||||
| 
 |  | ||||||
| 			//Stalling
 |  | ||||||
| 			bool backwardDirectionFlag = (!forwardDirection) ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward; |  | ||||||
| 			if(_forwardHeap->WasInserted( to )) { |  | ||||||
| 				if(backwardDirectionFlag) { |  | ||||||
| 					if(_forwardHeap->GetKey( to ) + edgeWeight < distance) { |  | ||||||
| 						return; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
|         for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) { |         for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) { | ||||||
| 			const NodeID to = _graph->GetTarget(edge); |             const EdgeData & data = _graph->GetEdgeData(edge); | ||||||
| 			const int edgeWeight = _graph->GetEdgeData(edge).distance; |             bool backwardDirectionFlag = (!forwardDirection) ? data.forward : data.backward; | ||||||
|  |             if(backwardDirectionFlag) { | ||||||
|  |                 const NodeID to = _graph->GetTarget(edge); | ||||||
|  |                 const int edgeWeight = data.distance; | ||||||
| 
 | 
 | ||||||
| 			assert( edgeWeight > 0 ); |                 assert( edgeWeight > 0 ); | ||||||
| 			bool forwardDirectionFlag = (forwardDirection ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward ); |  | ||||||
| 			if(forwardDirectionFlag) { |  | ||||||
| 	            const int toDistance = distance + edgeWeight; |  | ||||||
| //	            INFO((forwardDirection ? "[FORW]" : "[BACK]") << " relaxing edge (" << node << "," << to << ") with distance " << toDistance << "=" << distance << "+" << edgeWeight);
 |  | ||||||
| 
 | 
 | ||||||
| 				//New Node discovered -> Add to Heap + Node Info Storage
 |                 //Stalling
 | ||||||
| 				if ( !_forwardHeap->WasInserted( to ) ) { |                 if(_forwardHeap->WasInserted( to )) { | ||||||
| //				    INFO((forwardDirection ? "[FORW]" : "[BACK]") << " inserting node " << to << " at distance " << toDistance);
 |                     if(_forwardHeap->GetKey( to ) + edgeWeight < distance) { | ||||||
| 					_forwardHeap->Insert( to, toDistance, node ); |                         return; | ||||||
| 				} |                     } | ||||||
| 				//Found a shorter Path -> Update distance
 |                 } | ||||||
| 				else if ( toDistance < _forwardHeap->GetKey( to ) ) { |             } | ||||||
| 					_forwardHeap->GetData( to ).parent = node; |         } | ||||||
| 					_forwardHeap->DecreaseKey( to, toDistance ); | 
 | ||||||
| 					//new parent
 |         for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) { | ||||||
| 				} |             const EdgeData & data = _graph->GetEdgeData(edge); | ||||||
| 			} |             bool forwardDirectionFlag = (forwardDirection ? data.forward : data.backward ); | ||||||
| 		} |             if(forwardDirectionFlag) { | ||||||
|  | 
 | ||||||
|  |                 const NodeID to = _graph->GetTarget(edge); | ||||||
|  |                 const int edgeWeight = data.distance; | ||||||
|  | 
 | ||||||
|  |                 assert( edgeWeight > 0 ); | ||||||
|  |                 const int toDistance = distance + edgeWeight; | ||||||
|  | 
 | ||||||
|  |                 //New Node discovered -> Add to Heap + Node Info Storage
 | ||||||
|  |                 if ( !_forwardHeap->WasInserted( to ) ) { | ||||||
|  |                     _forwardHeap->Insert( to, toDistance, node ); | ||||||
|  |                 } | ||||||
|  |                 //Found a shorter Path -> Update distance
 | ||||||
|  |                 else if ( toDistance < _forwardHeap->GetKey( to ) ) { | ||||||
|  |                     _forwardHeap->GetData( to ).parent = node; | ||||||
|  |                     _forwardHeap->DecreaseKey( to, toDistance ); | ||||||
|  |                     //new parent
 | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     inline void _RoutingStepWithStats(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, int *_upperbound, _Statistics & stats) { |     inline void _RoutingStepWithStats(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, int *_upperbound, _Statistics & stats) { | ||||||
| @ -295,38 +301,38 @@ private: | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) { |         for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) { | ||||||
| 			const EdgeData& ed = _graph->GetEdgeData(edge); |             const EdgeData& ed = _graph->GetEdgeData(edge); | ||||||
| 			const NodeID to = _graph->GetTarget(edge); |             const NodeID to = _graph->GetTarget(edge); | ||||||
| 			const EdgeWeight edgeWeight = ed.distance; |             const EdgeWeight edgeWeight = ed.distance; | ||||||
| 
 | 
 | ||||||
| 			assert( edgeWeight > 0 ); |             assert( edgeWeight > 0 ); | ||||||
| 			const int toDistance = distance + edgeWeight; |             const int toDistance = distance + edgeWeight; | ||||||
| 
 | 
 | ||||||
| 			//Stalling
 |             //Stalling
 | ||||||
| 			if(_forwardHeap->WasInserted( to )) { |             if(_forwardHeap->WasInserted( to )) { | ||||||
| 				if(!forwardDirection ? ed.forward : ed.backward) { |                 if(!forwardDirection ? ed.forward : ed.backward) { | ||||||
| 					if(_forwardHeap->GetKey( to ) + edgeWeight < distance) { |                     if(_forwardHeap->GetKey( to ) + edgeWeight < distance) { | ||||||
| 						stats.stalledNodes++; |                         stats.stalledNodes++; | ||||||
| 						return; |                         return; | ||||||
| 					} |                     } | ||||||
| 				} |                 } | ||||||
| 			} |             } | ||||||
| 
 | 
 | ||||||
| 			if(forwardDirection ? ed.forward : ed.backward ) { |             if(forwardDirection ? ed.forward : ed.backward ) { | ||||||
| 				//New Node discovered -> Add to Heap + Node Info Storage
 |                 //New Node discovered -> Add to Heap + Node Info Storage
 | ||||||
| 				if ( !_forwardHeap->WasInserted( to ) ) { |                 if ( !_forwardHeap->WasInserted( to ) ) { | ||||||
| 					_forwardHeap->Insert( to, toDistance, node ); |                     _forwardHeap->Insert( to, toDistance, node ); | ||||||
| 					stats.insertedNodes++; |                     stats.insertedNodes++; | ||||||
| 				} |                 } | ||||||
| 				//Found a shorter Path -> Update distance
 |                 //Found a shorter Path -> Update distance
 | ||||||
| 				else if ( toDistance < _forwardHeap->GetKey( to ) ) { |                 else if ( toDistance < _forwardHeap->GetKey( to ) ) { | ||||||
| 					_forwardHeap->GetData( to ).parent = node; |                     _forwardHeap->GetData( to ).parent = node; | ||||||
| 					_forwardHeap->DecreaseKey( to, toDistance ); |                     _forwardHeap->DecreaseKey( to, toDistance ); | ||||||
| 					stats.decreasedNodes++; |                     stats.decreasedNodes++; | ||||||
| 					//new parent
 |                     //new parent
 | ||||||
| 				} |                 } | ||||||
| 			} |             } | ||||||
| 		} |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     inline bool _UnpackEdge(const NodeID source, const NodeID target, std::vector<_PathData> & path) { |     inline bool _UnpackEdge(const NodeID source, const NodeID target, std::vector<_PathData> & path) { | ||||||
| @ -355,19 +361,19 @@ private: | |||||||
| 
 | 
 | ||||||
|         assert(smallestWeight != INT_MAX); |         assert(smallestWeight != INT_MAX); | ||||||
| 
 | 
 | ||||||
| 		const EdgeData& ed = _graph->GetEdgeData(smallestEdge); |         const EdgeData& ed = _graph->GetEdgeData(smallestEdge); | ||||||
| //		INFO( (ed.shortcut ? "SHRT: " : "ORIG: ") << ed.distance << "," << ed.via);
 |         //		INFO( (ed.shortcut ? "SHRT: " : "ORIG: ") << ed.distance << "," << ed.via);
 | ||||||
| 		if(ed.shortcut) {//unpack
 |         if(ed.shortcut) {//unpack
 | ||||||
| 			const NodeID middle = ed.via; |             const NodeID middle = ed.via; | ||||||
| 			_UnpackEdge(source, middle, path); |             _UnpackEdge(source, middle, path); | ||||||
| 			_UnpackEdge(middle, target, path); |             _UnpackEdge(middle, target, path); | ||||||
| 			return false; |             return false; | ||||||
| 		} else { |         } else { | ||||||
| 			assert(!ed.shortcut); |             assert(!ed.shortcut); | ||||||
| 			path.push_back(_PathData(ed.via, ed.nameID1, ed.turnInstruction, ed.distance) ); |             path.push_back(_PathData(ed.via, ed.nameID1, ed.turnInstruction, ed.distance) ); | ||||||
| 			return true; |             return true; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| }; | }; | ||||||
| template<class EdgeData, class GraphT> HeapPtr SearchEngine<EdgeData, GraphT>::_forwardHeap; | template<class EdgeData, class GraphT> HeapPtr SearchEngine<EdgeData, GraphT>::_forwardHeap; | ||||||
| template<class EdgeData, class GraphT> HeapPtr SearchEngine<EdgeData, GraphT>::_backwardHeap; | template<class EdgeData, class GraphT> HeapPtr SearchEngine<EdgeData, GraphT>::_backwardHeap; | ||||||
|  | |||||||
							
								
								
									
										89
									
								
								Descriptors/BaseDescriptor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								Descriptors/BaseDescriptor.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | |||||||
|  | /*
 | ||||||
|  |     open source routing machine | ||||||
|  |     Copyright (C) Dennis Luxen, 2010 | ||||||
|  | 
 | ||||||
|  | This program is free software; you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU AFFERO General Public License as published by | ||||||
|  | the Free Software Foundation; either version 3 of the License, or | ||||||
|  | any later version. | ||||||
|  | 
 | ||||||
|  | This program is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with this program; if not, write to the Free Software | ||||||
|  | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||||
|  | or see http://www.gnu.org/licenses/agpl.txt.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef BASE_DESCRIPTOR_H_ | ||||||
|  | #define BASE_DESCRIPTOR_H_ | ||||||
|  | 
 | ||||||
|  | #include <cassert> | ||||||
|  | #include <cmath> | ||||||
|  | #include <cstdio> | ||||||
|  | #include <string> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include "../typedefs.h" | ||||||
|  | #include "../DataStructures/ExtractorStructs.h" | ||||||
|  | #include "../DataStructures/HashTable.h" | ||||||
|  | #include "../Util/StringUtil.h" | ||||||
|  | 
 | ||||||
|  | #include "../Plugins/RawRouteData.h" | ||||||
|  | 
 | ||||||
|  | static double areaThresholds[19] = { 5000, 5000, 5000, 5000, 5000, 2500, 2000, 1500, 800, 400, 250, 150, 100, 75, 25, 20, 10, 5, 0 }; | ||||||
|  | 
 | ||||||
|  | /* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/ | ||||||
|  | static double GetAngleBetweenTwoEdges(const _Coordinate& A, const _Coordinate& C, const _Coordinate& B) { | ||||||
|  |     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((double)v2y,v2x) - atan2((double)v1y,v1x) )*180/M_PI; | ||||||
|  |     while(angle < 0) | ||||||
|  |         angle += 360; | ||||||
|  | 
 | ||||||
|  |     return angle; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct _RouteSummary { | ||||||
|  |     std::string lengthString; | ||||||
|  |     std::string durationString; | ||||||
|  |     std::string startName; | ||||||
|  |     std::string destName; | ||||||
|  |     _RouteSummary() : lengthString("0"), durationString("0"), startName("unknown street"), destName("unknown street") {} | ||||||
|  |     void BuildDurationAndLengthStrings(unsigned distance, unsigned time) { | ||||||
|  |         //compute distance/duration for route summary
 | ||||||
|  |         std::ostringstream s; | ||||||
|  |         s << 10*(round(distance/10.)); | ||||||
|  |         lengthString = s.str(); | ||||||
|  |         int travelTime = time/10 + 1; | ||||||
|  |         s.str(""); | ||||||
|  |         s << travelTime; | ||||||
|  |         durationString = s.str(); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct _DescriptorConfig { | ||||||
|  |     _DescriptorConfig() : instructions(true), geometry(true), encodeGeometry(false), z(18) {} | ||||||
|  |     bool instructions; | ||||||
|  |     bool geometry; | ||||||
|  |     bool encodeGeometry; | ||||||
|  |     unsigned short z; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template<class SearchEngineT> | ||||||
|  | class BaseDescriptor { | ||||||
|  | public: | ||||||
|  |     BaseDescriptor() { } | ||||||
|  |     //Maybe someone can explain the pure virtual destructor thing to me (dennis)
 | ||||||
|  |     virtual ~BaseDescriptor() { } | ||||||
|  |     virtual void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned distance) = 0; | ||||||
|  |     virtual void SetConfig(const _DescriptorConfig & config) = 0; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif /* BASE_DESCRIPTOR_H_ */ | ||||||
							
								
								
									
										115
									
								
								Descriptors/DescriptionFactory.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								Descriptors/DescriptionFactory.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | |||||||
|  | /*
 | ||||||
|  |  open source routing machine | ||||||
|  |  Copyright (C) Dennis Luxen, others 2010 | ||||||
|  | 
 | ||||||
|  |  This program is free software; you can redistribute it and/or modify | ||||||
|  |  it under the terms of the GNU AFFERO General Public License as published by | ||||||
|  |  the Free Software Foundation; either version 3 of the License, or | ||||||
|  |  any later version. | ||||||
|  | 
 | ||||||
|  |  This program is distributed in the hope that it will be useful, | ||||||
|  |  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  |  You should have received a copy of the GNU Affero General Public License | ||||||
|  |  along with this program; if not, write to the Free Software | ||||||
|  |  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||||
|  |  or see http://www.gnu.org/licenses/agpl.txt.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <boost/foreach.hpp> | ||||||
|  | 
 | ||||||
|  | #include "../typedefs.h" | ||||||
|  | #include "DescriptionFactory.h" | ||||||
|  | 
 | ||||||
|  | DescriptionFactory::DescriptionFactory() { } | ||||||
|  | 
 | ||||||
|  | DescriptionFactory::~DescriptionFactory() { } | ||||||
|  | 
 | ||||||
|  | double DescriptionFactory::GetAngleBetweenCoordinates() const { | ||||||
|  |     return 0.;//GetAngleBetweenTwoEdges(previousCoordinate, currentCoordinate, nextCoordinate);
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DescriptionFactory::SetStartSegment(const PhantomNode & _startPhantom) { | ||||||
|  |     startPhantom = _startPhantom; | ||||||
|  |     AppendSegment(_startPhantom.location, _PathData(0, _startPhantom.nodeBasedEdgeNameID, 10, _startPhantom.weight1)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) { | ||||||
|  |     targetPhantom = _targetPhantom; | ||||||
|  |     AppendSegment(_targetPhantom.location, _PathData(0, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DescriptionFactory::AppendSegment(const _Coordinate & coordinate, const _PathData & data ) { | ||||||
|  |     //Segment information has following format:
 | ||||||
|  |     //["instruction","streetname",length,position,time,"length","earth_direction",azimuth]
 | ||||||
|  |     //Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5]
 | ||||||
|  |     //See also: http://developers.cloudmade.com/wiki/navengine/JSON_format
 | ||||||
|  | //    (_Coordinate & loc, NodeID nam, unsigned len, unsigned dur, short tInstr)
 | ||||||
|  | 
 | ||||||
|  |     //Is a new instruction necessary?
 | ||||||
|  |     //yes: data.turnInstruction != 0;
 | ||||||
|  |     //no: data.turnInstruction == 0;
 | ||||||
|  |     pathDescription.push_back(SegmentInformation(coordinate, data.nameID, 0, data.durationOfSegment, data.turnInstruction) ); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DescriptionFactory::AppendRouteInstructionString(std::string & output) { | ||||||
|  |     output += "[\"Turn left\",\"High Street\",200,0,10,\"200m\",\"NE\",22.5]"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DescriptionFactory::AppendEncodedPolylineString(std::string & output, bool isEncoded) { | ||||||
|  |     if(isEncoded) | ||||||
|  |         pc.printEncodedString(pathDescription, output); | ||||||
|  |     else | ||||||
|  |         pc.printUnencodedString(pathDescription, output); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DescriptionFactory::AppendEncodedPolylineString(std::string &output) { | ||||||
|  |     pc.printEncodedString(pathDescription, output); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DescriptionFactory::AppendUnencodedPolylineString(std::string &output) { | ||||||
|  |     pc.printUnencodedString(pathDescription, output); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | unsigned DescriptionFactory::Run() { | ||||||
|  |     if(0 == pathDescription.size()) | ||||||
|  |         return 0; | ||||||
|  | 
 | ||||||
|  |     unsigned entireLength = 0; | ||||||
|  |     /** starts at index 1 */ | ||||||
|  |     pathDescription[0].length = 0; | ||||||
|  |     for(unsigned i = 1; i < pathDescription.size(); ++i) { | ||||||
|  |         pathDescription[i].length = ApproximateDistance(pathDescription[i-1].location, pathDescription[i].location); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     unsigned lengthOfSegment = 0; | ||||||
|  |     unsigned durationOfSegment = 0; | ||||||
|  |     unsigned indexOfSegmentBegin = 0; | ||||||
|  | 
 | ||||||
|  |     for(unsigned i = 1; i < pathDescription.size(); ++i) { | ||||||
|  |         entireLength += pathDescription[i].length; | ||||||
|  |         lengthOfSegment += pathDescription[i].length; | ||||||
|  |         durationOfSegment += pathDescription[i].duration; | ||||||
|  |         pathDescription[indexOfSegmentBegin].length = lengthOfSegment; | ||||||
|  |         pathDescription[indexOfSegmentBegin].duration = durationOfSegment; | ||||||
|  |         if(pathDescription[i].turnInstruction != 0) { | ||||||
|  |             //INFO("Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID);
 | ||||||
|  |             assert(pathDescription[i].necessary); | ||||||
|  |             lengthOfSegment = 0; | ||||||
|  |             durationOfSegment = 0; | ||||||
|  |             indexOfSegmentBegin = i; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //Generalize poly line
 | ||||||
|  |     BOOST_FOREACH(SegmentInformation & segment, pathDescription) { | ||||||
|  |         //TODO: Replace me by real generalization
 | ||||||
|  |         segment.necessary = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //fix what needs to be fixed else
 | ||||||
|  |     return entireLength; | ||||||
|  | } | ||||||
							
								
								
									
										176
									
								
								Descriptors/DescriptionFactory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								Descriptors/DescriptionFactory.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,176 @@ | |||||||
|  | /*
 | ||||||
|  |  open source routing machine | ||||||
|  |  Copyright (C) Dennis Luxen, others 2010 | ||||||
|  | 
 | ||||||
|  |  This program is free software; you can redistribute it and/or modify | ||||||
|  |  it under the terms of the GNU AFFERO General Public License as published by | ||||||
|  |  the Free Software Foundation; either version 3 of the License, or | ||||||
|  |  any later version. | ||||||
|  | 
 | ||||||
|  |  This program is distributed in the hope that it will be useful, | ||||||
|  |  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  |  You should have received a copy of the GNU Affero General Public License | ||||||
|  |  along with this program; if not, write to the Free Software | ||||||
|  |  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||||
|  |  or see http://www.gnu.org/licenses/agpl.txt.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef DESCRIPTIONFACTORY_H_ | ||||||
|  | #define DESCRIPTIONFACTORY_H_ | ||||||
|  | 
 | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include "../Algorithms/PolylineCompressor.h" | ||||||
|  | #include "../DataStructures/ExtractorStructs.h" | ||||||
|  | #include "../DataStructures/SegmentInformation.h" | ||||||
|  | 
 | ||||||
|  | /* This class is fed with all way segments in consecutive order
 | ||||||
|  |  *  and produces the description plus the encoded polyline */ | ||||||
|  | 
 | ||||||
|  | class DescriptionFactory { | ||||||
|  |     PolylineCompressor pc; | ||||||
|  |     PhantomNode startPhantom, targetPhantom; | ||||||
|  | public: | ||||||
|  |     //I know, declaring this public is considered bad. I'm lazy
 | ||||||
|  |     std::vector <SegmentInformation> pathDescription; | ||||||
|  |     DescriptionFactory(); | ||||||
|  |     virtual ~DescriptionFactory(); | ||||||
|  |     double GetAngleBetweenCoordinates() const; | ||||||
|  |     void AppendEncodedPolylineString(std::string &output); | ||||||
|  |     void AppendUnencodedPolylineString(std::string &output); | ||||||
|  |     void AppendSegment(const _Coordinate & coordinate, const _PathData & data); | ||||||
|  |     void AppendRouteInstructionString(std::string & output); | ||||||
|  |     void SetStartSegment(const PhantomNode & startPhantom); | ||||||
|  |     void SetEndSegment(const PhantomNode & startPhantom); | ||||||
|  |     void AppendEncodedPolylineString(std::string & output, bool isEncoded); | ||||||
|  |     unsigned Run(); | ||||||
|  | 
 | ||||||
|  | //    static inline void getDirectionOfInstruction(double angle, DirectionOfInstruction & dirInst) {
 | ||||||
|  | //        if(angle >= 23 && angle < 67) {
 | ||||||
|  | //            dirInst.direction = "southeast";
 | ||||||
|  | //            dirInst.shortDirection = "SE";
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if(angle >= 67 && angle < 113) {
 | ||||||
|  | //            dirInst.direction = "south";
 | ||||||
|  | //            dirInst.shortDirection = "S";
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if(angle >= 113 && angle < 158) {
 | ||||||
|  | //            dirInst.direction = "southwest";
 | ||||||
|  | //            dirInst.shortDirection = "SW";
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if(angle >= 158 && angle < 202) {
 | ||||||
|  | //            dirInst.direction = "west";
 | ||||||
|  | //            dirInst.shortDirection = "W";
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if(angle >= 202 && angle < 248) {
 | ||||||
|  | //            dirInst.direction = "northwest";
 | ||||||
|  | //            dirInst.shortDirection = "NW";
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if(angle >= 248 && angle < 292) {
 | ||||||
|  | //            dirInst.direction = "north";
 | ||||||
|  | //            dirInst.shortDirection = "N";
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if(angle >= 292 && angle < 336) {
 | ||||||
|  | //            dirInst.direction = "northeast";
 | ||||||
|  | //            dirInst.shortDirection = "NE";
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        dirInst.direction = "East";
 | ||||||
|  | //        dirInst.shortDirection = "E";
 | ||||||
|  | //        return;
 | ||||||
|  | //    }
 | ||||||
|  | //
 | ||||||
|  | //    static inline void getTurnDirectionOfInstruction(double angle, std::string & output) {
 | ||||||
|  | //        if(angle >= 23 && angle < 67) {
 | ||||||
|  | //            output = "Turn sharp right";
 | ||||||
|  | //    //        cout << "angle " << angle << "-> " << output << endl;
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if (angle >= 67 && angle < 113) {
 | ||||||
|  | //            output = "Turn right";
 | ||||||
|  | //    //        cout << "angle " << angle << "-> " << output << endl;
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if (angle >= 113 && angle < 158) {
 | ||||||
|  | //            output = "Bear right";
 | ||||||
|  | //    //        cout << "angle " << angle << "-> " << output << endl;
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //
 | ||||||
|  | //        if (angle >= 158 && angle < 202) {
 | ||||||
|  | //            output = "Continue";
 | ||||||
|  | //    //        cout << "angle " << angle << "-> " << output << endl;
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if (angle >= 202 && angle < 248) {
 | ||||||
|  | //            output = "Bear left";
 | ||||||
|  | //    //        cout << "angle " << angle << "-> " << output << endl;
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if (angle >= 248 && angle < 292) {
 | ||||||
|  | //            output = "Turn left";
 | ||||||
|  | //    //        cout << "angle " << angle << "-> " << output << endl;
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        if (angle >= 292 && angle < 336) {
 | ||||||
|  | //            output = "Turn sharp left";
 | ||||||
|  | //    //        cout << "angle " << angle << "-> " << output << endl;
 | ||||||
|  | //            return;
 | ||||||
|  | //        }
 | ||||||
|  | //        output = "U-Turn";
 | ||||||
|  | //    //    cout << "angle " << angle << "-> " << output << endl;
 | ||||||
|  | //    }
 | ||||||
|  | //private:
 | ||||||
|  | //    void appendInstructionNameToString(const std::string & nameOfStreet, const std::string & instructionOrDirection, std::string &output, bool firstAdvice = false) {
 | ||||||
|  | //        output += "[";
 | ||||||
|  | //        if(config.instructions) {
 | ||||||
|  | //            output += "\"";
 | ||||||
|  | //            if(firstAdvice) {
 | ||||||
|  | //                output += "Head ";
 | ||||||
|  | //            }
 | ||||||
|  | //            output += instructionOrDirection;
 | ||||||
|  | //            output += "\",\"";
 | ||||||
|  | //            output += nameOfStreet;
 | ||||||
|  | //            output += "\",";
 | ||||||
|  | //        }
 | ||||||
|  | //    }
 | ||||||
|  | //
 | ||||||
|  | //    void appendInstructionLengthToString(unsigned length, std::string &output) {
 | ||||||
|  | //        if(config.instructions){
 | ||||||
|  | //            std::string tmpDistance;
 | ||||||
|  | //            intToString(10*(round(length/10.)), tmpDistance);
 | ||||||
|  | //            output += tmpDistance;
 | ||||||
|  | //            output += ",";
 | ||||||
|  | //            intToString(descriptionFactory.startIndexOfGeometry, tmp);
 | ||||||
|  | //            output += tmp;
 | ||||||
|  | //            output += ",";
 | ||||||
|  | //            intToString(descriptionFactory.durationOfInstruction, tmp);
 | ||||||
|  | //            output += tmp;
 | ||||||
|  | //            output += ",";
 | ||||||
|  | //            output += "\"";
 | ||||||
|  | //            output += tmpDistance;
 | ||||||
|  | //            output += "\",";
 | ||||||
|  | //            double angle = descriptionFactory.GetAngleBetweenCoordinates();
 | ||||||
|  | //            DirectionOfInstruction direction;
 | ||||||
|  | //            getDirectionOfInstruction(angle, direction);
 | ||||||
|  | //            output += "\"";
 | ||||||
|  | //            output += direction.shortDirection;
 | ||||||
|  | //            output += "\",";
 | ||||||
|  | //            std::stringstream numberString;
 | ||||||
|  | //            numberString << fixed << setprecision(2) << angle;
 | ||||||
|  | //            output += numberString.str();
 | ||||||
|  | //        }
 | ||||||
|  | //        output += "]";
 | ||||||
|  | //    }
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif /* DESCRIPTIONFACTORY_H_ */ | ||||||
							
								
								
									
										67
									
								
								Descriptors/GPXDescriptor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Descriptors/GPXDescriptor.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | |||||||
|  | /*
 | ||||||
|  |     open source routing machine | ||||||
|  |     Copyright (C) Dennis Luxen, others 2010 | ||||||
|  | 
 | ||||||
|  | This program is free software; you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU AFFERO General Public License as published by | ||||||
|  | the Free Software Foundation; either version 3 of the License, or | ||||||
|  | any later version. | ||||||
|  | 
 | ||||||
|  | This program is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with this program; if not, write to the Free Software | ||||||
|  | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||||
|  | or see http://www.gnu.org/licenses/agpl.txt.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef GPX_DESCRIPTOR_H_ | ||||||
|  | #define GPX_DESCRIPTOR_H_ | ||||||
|  | 
 | ||||||
|  | #include <boost/foreach.hpp> | ||||||
|  | #include "BaseDescriptor.h" | ||||||
|  | 
 | ||||||
|  | template<class SearchEngineT> | ||||||
|  | class GPXDescriptor : public BaseDescriptor<SearchEngineT>{ | ||||||
|  | private: | ||||||
|  |     _DescriptorConfig config; | ||||||
|  |     _Coordinate current; | ||||||
|  | 
 | ||||||
|  |     std::string tmp; | ||||||
|  | public: | ||||||
|  |     void SetConfig(const _DescriptorConfig& c) { config = c; } | ||||||
|  |     void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned distance) { | ||||||
|  |         reply.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); | ||||||
|  |         reply.content += "<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" " | ||||||
|  |                 "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " | ||||||
|  |                 "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd" | ||||||
|  |                 "\">"; | ||||||
|  |         reply.content += "<rte>"; | ||||||
|  |         if(distance != UINT_MAX && rawRoute.routeSegments.size()) { | ||||||
|  |             convertInternalLatLonToString(phantomNodes.startPhantom.location.lat, tmp); | ||||||
|  |             reply.content += "<rtept lat=\"" + tmp + "\" "; | ||||||
|  |             convertInternalLatLonToString(phantomNodes.startPhantom.location.lon, tmp); | ||||||
|  |             reply.content += "lon=\"" + tmp + "\"></rtept>"; | ||||||
|  | 
 | ||||||
|  |             for(unsigned segmentIdx = 0; segmentIdx < rawRoute.routeSegments.size(); segmentIdx++) { | ||||||
|  |                 BOOST_FOREACH(_PathData pathData, rawRoute.routeSegments[segmentIdx]) { | ||||||
|  |                     sEngine.GetCoordinatesForNodeID(pathData.node, current); | ||||||
|  | 
 | ||||||
|  |                     convertInternalLatLonToString(current.lat, tmp); | ||||||
|  |                     reply.content += "<rtept lat=\"" + tmp + "\" "; | ||||||
|  |                     convertInternalLatLonToString(current.lon, tmp); | ||||||
|  |                     reply.content += "lon=\"" + tmp + "\"></rtept>"; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             convertInternalLatLonToString(phantomNodes.targetPhantom.location.lat, tmp); | ||||||
|  |             reply.content += "<rtept lat=\"" + tmp + "\" "; | ||||||
|  |             convertInternalLatLonToString(phantomNodes.targetPhantom.location.lon, tmp); | ||||||
|  |             reply.content += "lon=\"" + tmp + "\"></rtept>"; | ||||||
|  |         } | ||||||
|  |         reply.content += "</rte></gpx>"; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | #endif /* GPX_DESCRIPTOR_H_ */ | ||||||
							
								
								
									
										154
									
								
								Descriptors/JSONDescriptor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								Descriptors/JSONDescriptor.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,154 @@ | |||||||
|  | /*
 | ||||||
|  |     open source routing machine | ||||||
|  |     Copyright (C) Dennis Luxen, others 2010 | ||||||
|  | 
 | ||||||
|  | This program is free software; you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU AFFERO General Public License as published by | ||||||
|  | the Free Software Foundation; either version 3 of the License, or | ||||||
|  | any later version. | ||||||
|  | 
 | ||||||
|  | This program is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with this program; if not, write to the Free Software | ||||||
|  | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||||
|  | or see http://www.gnu.org/licenses/agpl.txt.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef JSON_DESCRIPTOR_H_ | ||||||
|  | #define JSON_DESCRIPTOR_H_ | ||||||
|  | 
 | ||||||
|  | #include <boost/foreach.hpp> | ||||||
|  | 
 | ||||||
|  | #include "BaseDescriptor.h" | ||||||
|  | #include "DescriptionFactory.h" | ||||||
|  | #include "../DataStructures/SegmentInformation.h" | ||||||
|  | #include "../DataStructures/TurnInstructions.h" | ||||||
|  | #include "../Util/StringUtil.h" | ||||||
|  | 
 | ||||||
|  | template<class SearchEngineT> | ||||||
|  | class JSONDescriptor : public BaseDescriptor<SearchEngineT>{ | ||||||
|  | private: | ||||||
|  |     _DescriptorConfig config; | ||||||
|  |     _RouteSummary summary; | ||||||
|  |     DescriptionFactory descriptionFactory; | ||||||
|  |     std::string tmp; | ||||||
|  |     _Coordinate current; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     JSONDescriptor() {} | ||||||
|  |     void SetConfig(const _DescriptorConfig & c) { config = c; } | ||||||
|  | 
 | ||||||
|  |     void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned durationOfTrip) { | ||||||
|  |         WriteHeaderToOutput(reply.content); | ||||||
|  |         //We do not need to do much, if there is no route ;-)
 | ||||||
|  | 
 | ||||||
|  |         if(durationOfTrip != INT_MAX && rawRoute.routeSegments.size() > 0) { | ||||||
|  |             summary.startName = sEngine.GetEscapedNameForNameID(phantomNodes.startPhantom.nodeBasedEdgeNameID); | ||||||
|  |             descriptionFactory.SetStartSegment(phantomNodes.startPhantom); | ||||||
|  |             summary.destName = sEngine.GetEscapedNameForNameID(phantomNodes.targetPhantom.nodeBasedEdgeNameID); | ||||||
|  |             reply.content += "0," | ||||||
|  |                     "\"status_message\": \"Found route between points\","; | ||||||
|  |             for(unsigned segmentIdx = 0; segmentIdx < rawRoute.routeSegments.size(); segmentIdx++) { | ||||||
|  |                 const std::vector< _PathData > & path = rawRoute.routeSegments[segmentIdx]; | ||||||
|  |                 BOOST_FOREACH(_PathData pathData, path) { | ||||||
|  |                     sEngine.GetCoordinatesForNodeID(pathData.node, current); | ||||||
|  |                     descriptionFactory.AppendSegment(current, pathData ); | ||||||
|  |                 } | ||||||
|  |                 //TODO: Add via points
 | ||||||
|  |             } | ||||||
|  |             descriptionFactory.SetEndSegment(phantomNodes.targetPhantom); | ||||||
|  |         } else { | ||||||
|  |             //no route found
 | ||||||
|  |             reply.content += "207," | ||||||
|  |                     "\"status_message\": \"Cannot find route between points\","; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         summary.BuildDurationAndLengthStrings(descriptionFactory.Run(), durationOfTrip); | ||||||
|  | 
 | ||||||
|  |         reply.content += "\"route_summary\": {" | ||||||
|  |                 "\"total_distance\":"; | ||||||
|  |         reply.content += summary.lengthString; | ||||||
|  |         reply.content += "," | ||||||
|  |                 "\"total_time\":"; | ||||||
|  |         reply.content += summary.durationString; | ||||||
|  |         reply.content += "," | ||||||
|  |                 "\"start_point\":\""; | ||||||
|  |         reply.content += summary.startName; | ||||||
|  |         reply.content += "\"," | ||||||
|  |                 "\"end_point\":\""; | ||||||
|  |         reply.content += summary.destName; | ||||||
|  |         reply.content += "\""; | ||||||
|  |         reply.content += "},"; | ||||||
|  |         reply.content += "\"route_geometry\": "; | ||||||
|  |         if(config.geometry) { | ||||||
|  |             if(config.encodeGeometry) | ||||||
|  |                 descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry); | ||||||
|  |         } else { | ||||||
|  |             reply.content += "[]"; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         reply.content += "," | ||||||
|  |                 "\"route_instructions\": ["; | ||||||
|  |         if(config.instructions) { | ||||||
|  |             unsigned prefixSumOfNecessarySegments = 0; | ||||||
|  |             std::string tmpDist, tmpLength, tmp; | ||||||
|  |             //Fetch data from Factory and generate a string from it.
 | ||||||
|  |             BOOST_FOREACH(SegmentInformation segment, descriptionFactory.pathDescription) { | ||||||
|  |                 //["instruction","streetname",length,position,time,"length","earth_direction",azimuth]
 | ||||||
|  |                 if(0 != segment.turnInstruction) { | ||||||
|  |                     if(0 != prefixSumOfNecessarySegments) | ||||||
|  |                         reply.content += ","; | ||||||
|  |                     reply.content += "[\""; | ||||||
|  |                     reply.content += TurnInstructions.TurnStrings[segment.turnInstruction]; | ||||||
|  |                     reply.content += "\",\""; | ||||||
|  |                     reply.content += sEngine.GetEscapedNameForNameID(segment.nameID); | ||||||
|  |                     reply.content += "\","; | ||||||
|  |                     intToString(segment.length, tmpDist); | ||||||
|  |                     reply.content += tmpDist; | ||||||
|  |                     reply.content += ","; | ||||||
|  |                     intToString(prefixSumOfNecessarySegments, tmpLength); | ||||||
|  |                     reply.content += tmpLength; | ||||||
|  |                     reply.content += ","; | ||||||
|  |                     intToString(segment.duration, tmp); | ||||||
|  |                     reply.content += ",\""; | ||||||
|  |                     reply.content += tmpLength; | ||||||
|  |                     //TODO: fix heading
 | ||||||
|  |                     reply.content += "\",\"NE\",22.5"; | ||||||
|  |                     reply.content += "]"; | ||||||
|  |                 } | ||||||
|  |                 if(segment.necessary) | ||||||
|  |                     ++prefixSumOfNecessarySegments; | ||||||
|  |             } | ||||||
|  |             //            descriptionFactory.AppendRouteInstructionString(reply.content);
 | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |         reply.content += "],"; | ||||||
|  |         //list all viapoints so that the client may display it
 | ||||||
|  |         reply.content += "\"via_points\":["; | ||||||
|  |         for(unsigned segmentIdx = 1; (true == config.geometry) && (segmentIdx < rawRoute.segmentEndCoordinates.size()); segmentIdx++) { | ||||||
|  |             if(segmentIdx > 1) | ||||||
|  |                 reply.content += ","; | ||||||
|  |             reply.content += "["; | ||||||
|  |             if(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location.isSet()) | ||||||
|  |                 convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location, tmp); | ||||||
|  |             else | ||||||
|  |                 convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates[segmentIdx], tmp); | ||||||
|  |             reply.content += tmp; | ||||||
|  |             reply.content += "]"; | ||||||
|  |         } | ||||||
|  |         reply.content += "]," | ||||||
|  |                 "\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.2)\""; | ||||||
|  |         reply.content += "}"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void WriteHeaderToOutput(std::string & output) { | ||||||
|  |         output += "{" | ||||||
|  |                 "\"version\": 0.3," | ||||||
|  |                 "\"status\":"; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | #endif /* JSON_DESCRIPTOR_H_ */ | ||||||
| @ -29,11 +29,11 @@ or see http://www.gnu.org/licenses/agpl.txt. | |||||||
| 
 | 
 | ||||||
| #include "ObjectForPluginStruct.h" | #include "ObjectForPluginStruct.h" | ||||||
| 
 | 
 | ||||||
| #include "BaseDescriptor.h" |  | ||||||
| #include "BasePlugin.h" | #include "BasePlugin.h" | ||||||
| #include "RouteParameters.h" | #include "RouteParameters.h" | ||||||
| #include "GPXDescriptor.h" | #include "../Descriptors/BaseDescriptor.h" | ||||||
| #include "JSONDescriptor.h" | #include "../Descriptors/GPXDescriptor.h" | ||||||
|  | #include "../Descriptors/JSONDescriptor.h" | ||||||
| 
 | 
 | ||||||
| #include "../DataStructures/HashTable.h" | #include "../DataStructures/HashTable.h" | ||||||
| #include "../DataStructures/StaticGraph.h" | #include "../DataStructures/StaticGraph.h" | ||||||
| @ -131,7 +131,6 @@ public: | |||||||
|         rawRoute.Resize(); |         rawRoute.Resize(); | ||||||
|         unsigned distance = 0; |         unsigned distance = 0; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|         //single route or via point routing
 |         //single route or via point routing
 | ||||||
|         if(0 == routeParameters.viaPoints.size()) { |         if(0 == routeParameters.viaPoints.size()) { | ||||||
|             PhantomNodes segmentPhantomNodes; |             PhantomNodes segmentPhantomNodes; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user