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 <string> | ||||
| #include <boost/unordered_map.hpp> | ||||
| #include "../typedefs.h" | ||||
| #include "Util.h" | ||||
| 
 | ||||
| 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; | ||||
|     unsigned nameID; | ||||
|     unsigned lengthOfSegment; | ||||
|     unsigned durationOfSegment; | ||||
|     short turnInstruction; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -100,20 +100,21 @@ public: | ||||
|             INFO("TODO: Start and target are on same edge") | ||||
|                                     return _upperbound; | ||||
|         } | ||||
|         double time1 = get_timestamp(); | ||||
|         //insert start and/or target node of start edge
 | ||||
|         _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) { | ||||
|             _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
 | ||||
|         _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) { | ||||
|             _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){ | ||||
| @ -124,8 +125,8 @@ public: | ||||
|                 _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 ) { | ||||
|             return _upperbound; | ||||
|         } | ||||
| @ -135,17 +136,20 @@ public: | ||||
|             pathNode = _forwardHeap->GetData(pathNode).parent; | ||||
|             packedPath.push_front(pathNode); | ||||
|         } | ||||
| //        INFO("Finished getting packed forward path: " << packedPath.size());
 | ||||
|         //        INFO("Finished getting packed forward path: " << packedPath.size());
 | ||||
|         packedPath.push_back(middle); | ||||
|         pathNode = middle; | ||||
|         while(phantomNodes.targetPhantom.edgeBasedNode != pathNode && (!phantomNodes.targetPhantom.isBidirected || phantomNodes.targetPhantom.edgeBasedNode+1 != pathNode)) { | ||||
|             pathNode = _backwardHeap->GetData(pathNode).parent; | ||||
|             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++){ | ||||
|             _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; | ||||
|     } | ||||
| 
 | ||||
| @ -222,7 +226,7 @@ private: | ||||
|     inline void _RoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, int *_upperbound) { | ||||
|         const NodeID node = _forwardHeap->DeleteMin(); | ||||
|         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)){ | ||||
|             const int newDistance = _backwardHeap->GetKey(node) + distance; | ||||
|             if(newDistance < *_upperbound){ | ||||
| @ -235,16 +239,18 @@ private: | ||||
|             _forwardHeap->DeleteAll(); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         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 int edgeWeight = _graph->GetEdgeData(edge).distance; | ||||
|                 const int edgeWeight = data.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; | ||||
|                     } | ||||
| @ -253,18 +259,18 @@ private: | ||||
|         } | ||||
| 
 | ||||
|         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 = _graph->GetEdgeData(edge).distance; | ||||
|                 const int edgeWeight = data.distance; | ||||
| 
 | ||||
|                 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
 | ||||
|                 if ( !_forwardHeap->WasInserted( to ) ) { | ||||
| //				    INFO((forwardDirection ? "[FORW]" : "[BACK]") << " inserting node " << to << " at distance " << toDistance);
 | ||||
|                     _forwardHeap->Insert( to, toDistance, node ); | ||||
|                 } | ||||
|                 //Found a shorter Path -> Update distance
 | ||||
| @ -356,7 +362,7 @@ private: | ||||
|         assert(smallestWeight != INT_MAX); | ||||
| 
 | ||||
|         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
 | ||||
|             const NodeID middle = ed.via; | ||||
|             _UnpackEdge(source, middle, path); | ||||
|  | ||||
							
								
								
									
										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 "BaseDescriptor.h" | ||||
| #include "BasePlugin.h" | ||||
| #include "RouteParameters.h" | ||||
| #include "GPXDescriptor.h" | ||||
| #include "JSONDescriptor.h" | ||||
| #include "../Descriptors/BaseDescriptor.h" | ||||
| #include "../Descriptors/GPXDescriptor.h" | ||||
| #include "../Descriptors/JSONDescriptor.h" | ||||
| 
 | ||||
| #include "../DataStructures/HashTable.h" | ||||
| #include "../DataStructures/StaticGraph.h" | ||||
| @ -131,7 +131,6 @@ public: | ||||
|         rawRoute.Resize(); | ||||
|         unsigned distance = 0; | ||||
| 
 | ||||
| 
 | ||||
|         //single route or via point routing
 | ||||
|         if(0 == routeParameters.viaPoints.size()) { | ||||
|             PhantomNodes segmentPhantomNodes; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user