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; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -100,6 +100,7 @@ public: | |||||||
|             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);
 | ||||||
| @ -125,7 +126,7 @@ public: | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         //        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; | ||||||
|         } |         } | ||||||
| @ -146,6 +147,9 @@ public: | |||||||
|         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; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -235,16 +239,18 @@ private: | |||||||
|             _forwardHeap->DeleteAll(); |             _forwardHeap->DeleteAll(); | ||||||
|             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 & data = _graph->GetEdgeData(edge); | ||||||
|  |             bool backwardDirectionFlag = (!forwardDirection) ? data.forward : data.backward; | ||||||
|  |             if(backwardDirectionFlag) { | ||||||
|                 const NodeID to = _graph->GetTarget(edge); |                 const NodeID to = _graph->GetTarget(edge); | ||||||
| 			const int edgeWeight = _graph->GetEdgeData(edge).distance; |                 const int edgeWeight = data.distance; | ||||||
| 
 | 
 | ||||||
|                 assert( edgeWeight > 0 ); |                 assert( edgeWeight > 0 ); | ||||||
| 
 | 
 | ||||||
|                 //Stalling
 |                 //Stalling
 | ||||||
| 			bool backwardDirectionFlag = (!forwardDirection) ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward; |  | ||||||
|                 if(_forwardHeap->WasInserted( to )) { |                 if(_forwardHeap->WasInserted( to )) { | ||||||
| 				if(backwardDirectionFlag) { |  | ||||||
|                     if(_forwardHeap->GetKey( to ) + edgeWeight < distance) { |                     if(_forwardHeap->GetKey( to ) + edgeWeight < distance) { | ||||||
|                         return; |                         return; | ||||||
|                     } |                     } | ||||||
| @ -253,18 +259,18 @@ private: | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         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 & data = _graph->GetEdgeData(edge); | ||||||
|  |             bool forwardDirectionFlag = (forwardDirection ? data.forward : data.backward ); | ||||||
|  |             if(forwardDirectionFlag) { | ||||||
|  | 
 | ||||||
|                 const NodeID to = _graph->GetTarget(edge); |                 const NodeID to = _graph->GetTarget(edge); | ||||||
| 			const int edgeWeight = _graph->GetEdgeData(edge).distance; |                 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; |                 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
 |                 //New Node discovered -> Add to Heap + Node Info Storage
 | ||||||
|                 if ( !_forwardHeap->WasInserted( to ) ) { |                 if ( !_forwardHeap->WasInserted( to ) ) { | ||||||
| //				    INFO((forwardDirection ? "[FORW]" : "[BACK]") << " inserting node " << to << " at distance " << toDistance);
 |  | ||||||
|                     _forwardHeap->Insert( to, toDistance, node ); |                     _forwardHeap->Insert( to, toDistance, node ); | ||||||
|                 } |                 } | ||||||
|                 //Found a shorter Path -> Update distance
 |                 //Found a shorter Path -> Update distance
 | ||||||
|  | |||||||
							
								
								
									
										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