diff --git a/Descriptors/JSONDescriptor.h b/Descriptors/JSONDescriptor.h index 4fe37108e..029e50d11 100644 --- a/Descriptors/JSONDescriptor.h +++ b/Descriptors/JSONDescriptor.h @@ -32,145 +32,146 @@ or see http://www.gnu.org/licenses/agpl.txt. template class JSONDescriptor : public BaseDescriptor{ private: - _DescriptorConfig config; - _RouteSummary summary; - DescriptionFactory descriptionFactory; - std::string tmp; - _Coordinate current; - struct { - int startIndex; - int nameID; - int leaveAtExit; - } roundAbout; + _DescriptorConfig config; + _RouteSummary summary; + DescriptionFactory descriptionFactory; + _Coordinate current; + struct { + int startIndex; + int nameID; + int leaveAtExit; + } roundAbout; public: - JSONDescriptor() {} - void SetConfig(const _DescriptorConfig & c) { config = c; } + JSONDescriptor() {} + void SetConfig(const _DescriptorConfig & c) { config = c; } - void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned durationOfTrip) { - WriteHeaderToOutput(reply.content); - 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 { - //We do not need to do much, if there is no route ;-) - reply.content += "207," - "\"status_message\": \"Cannot find route between points\","; - } + void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, const unsigned durationOfTrip) { + WriteHeaderToOutput(reply.content); + 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) { + BOOST_FOREACH(_PathData & pathData, rawRoute.routeSegments[segmentIdx]) { + sEngine.GetCoordinatesForNodeID(pathData.node, current); + descriptionFactory.AppendSegment(current, pathData ); + } + } + descriptionFactory.SetEndSegment(phantomNodes.targetPhantom); + } else { + //We do not need to do much, if there is no route ;-) + reply.content += "207," + "\"status_message\": \"Cannot find route between points\","; + } - summary.BuildDurationAndLengthStrings(descriptionFactory.Run(config.z), durationOfTrip); + summary.BuildDurationAndLengthStrings(descriptionFactory.Run(config.z), 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_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) { - //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 - unsigned prefixSumOfNecessarySegments = 0; - roundAbout.leaveAtExit = 0; - roundAbout.nameID = 0; - std::string tmpDist, tmpLength, tmp; - //Fetch data from Factory and generate a string from it. - BOOST_FOREACH(SegmentInformation segment, descriptionFactory.pathDescription) { - if(TurnInstructions.TurnIsNecessary( segment.turnInstruction) ) { - if(TurnInstructions.EnterRoundAbout == segment.turnInstruction) { - roundAbout.nameID = segment.nameID; - roundAbout.startIndex = prefixSumOfNecessarySegments; - } else { - if(0 != prefixSumOfNecessarySegments) - reply.content += ","; + reply.content += "," + "\"route_instructions\": ["; + if(config.instructions) { + //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 + unsigned prefixSumOfNecessarySegments = 0; + roundAbout.leaveAtExit = 0; + roundAbout.nameID = 0; + std::string tmpDist, tmpLength, tmpDuration; + //Fetch data from Factory and generate a string from it. + BOOST_FOREACH(SegmentInformation & segment, descriptionFactory.pathDescription) { + if(TurnInstructions.TurnIsNecessary( segment.turnInstruction) ) { + if(TurnInstructions.EnterRoundAbout == segment.turnInstruction) { + roundAbout.nameID = segment.nameID; + roundAbout.startIndex = prefixSumOfNecessarySegments; + } else { + if(0 != prefixSumOfNecessarySegments) + reply.content += ","; - reply.content += "[\""; - if(TurnInstructions.LeaveRoundAbout == segment.turnInstruction) { - reply.content += TurnInstructions.TurnStrings[TurnInstructions.EnterRoundAbout]; - reply.content += " and leave at "; - reply.content += TurnInstructions.Ordinals[roundAbout.leaveAtExit+1]; - reply.content += " exit"; - roundAbout.leaveAtExit = 0; - } else { - 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 += "]"; - } - } else if(TurnInstructions.StayOnRoundAbout == segment.turnInstruction) { - ++roundAbout.leaveAtExit; - } - if(segment.necessary) - ++prefixSumOfNecessarySegments; - } - } - 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 += "}"; - } + reply.content += "[\""; + if(TurnInstructions.LeaveRoundAbout == segment.turnInstruction) { + reply.content += TurnInstructions.TurnStrings[TurnInstructions.EnterRoundAbout]; + reply.content += " and leave at "; + reply.content += TurnInstructions.Ordinals[roundAbout.leaveAtExit+1]; + reply.content += " exit"; + roundAbout.leaveAtExit = 0; + } else { + 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, tmpDuration); + reply.content += tmpDuration; + reply.content += ",\""; + reply.content += tmpLength; + //TODO: fix heading + reply.content += "\",\"NE\",22.5"; + reply.content += "]"; + } + } else if(TurnInstructions.StayOnRoundAbout == segment.turnInstruction) { + ++roundAbout.leaveAtExit; + } + if(segment.necessary) + ++prefixSumOfNecessarySegments; + } + } + reply.content += "],"; + //list all viapoints so that the client may display it + reply.content += "\"via_points\":["; + if(true == config.geometry) { + std::string tmp; + for(unsigned segmentIdx = 1; 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.3)\""; + reply.content += "}"; + } - void WriteHeaderToOutput(std::string & output) { - output += "{" - "\"version\": 0.3," - "\"status\":"; - } + inline void WriteHeaderToOutput(std::string & output) { + output += "{" + "\"version\": 0.3," + "\"status\":"; + } }; #endif /* JSON_DESCRIPTOR_H_ */