Fixes issue 63

This commit is contained in:
DennisOSRM 2011-12-17 13:44:01 +01:00
parent f5226b2228
commit b133beed5e

View File

@ -32,145 +32,146 @@ or see http://www.gnu.org/licenses/agpl.txt.
template<class SearchEngineT> template<class SearchEngineT>
class JSONDescriptor : public BaseDescriptor<SearchEngineT>{ class JSONDescriptor : public BaseDescriptor<SearchEngineT>{
private: private:
_DescriptorConfig config; _DescriptorConfig config;
_RouteSummary summary; _RouteSummary summary;
DescriptionFactory descriptionFactory; DescriptionFactory descriptionFactory;
std::string tmp; _Coordinate current;
_Coordinate current; struct {
struct { int startIndex;
int startIndex; int nameID;
int nameID; int leaveAtExit;
int leaveAtExit; } roundAbout;
} roundAbout;
public: public:
JSONDescriptor() {} JSONDescriptor() {}
void SetConfig(const _DescriptorConfig & c) { config = c; } void SetConfig(const _DescriptorConfig & c) { config = c; }
void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned durationOfTrip) { void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, const unsigned durationOfTrip) {
WriteHeaderToOutput(reply.content); WriteHeaderToOutput(reply.content);
if(durationOfTrip != INT_MAX && rawRoute.routeSegments.size() > 0) { if(durationOfTrip != INT_MAX && rawRoute.routeSegments.size() > 0) {
summary.startName = sEngine.GetEscapedNameForNameID(phantomNodes.startPhantom.nodeBasedEdgeNameID); summary.startName = sEngine.GetEscapedNameForNameID(phantomNodes.startPhantom.nodeBasedEdgeNameID);
descriptionFactory.SetStartSegment(phantomNodes.startPhantom); descriptionFactory.SetStartSegment(phantomNodes.startPhantom);
summary.destName = sEngine.GetEscapedNameForNameID(phantomNodes.targetPhantom.nodeBasedEdgeNameID); summary.destName = sEngine.GetEscapedNameForNameID(phantomNodes.targetPhantom.nodeBasedEdgeNameID);
reply.content += "0," reply.content += "0,"
"\"status_message\": \"Found route between points\","; "\"status_message\": \"Found route between points\",";
for(unsigned segmentIdx = 0; segmentIdx < rawRoute.routeSegments.size(); segmentIdx++) { for(unsigned segmentIdx = 0; segmentIdx < rawRoute.routeSegments.size(); ++segmentIdx) {
const std::vector< _PathData > & path = rawRoute.routeSegments[segmentIdx]; BOOST_FOREACH(_PathData & pathData, rawRoute.routeSegments[segmentIdx]) {
BOOST_FOREACH(_PathData pathData, path) { sEngine.GetCoordinatesForNodeID(pathData.node, current);
sEngine.GetCoordinatesForNodeID(pathData.node, current); descriptionFactory.AppendSegment(current, pathData );
descriptionFactory.AppendSegment(current, pathData ); }
} }
//TODO: Add via points descriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
} } else {
descriptionFactory.SetEndSegment(phantomNodes.targetPhantom); //We do not need to do much, if there is no route ;-)
} else { reply.content += "207,"
//We do not need to do much, if there is no route ;-) "\"status_message\": \"Cannot find route between points\",";
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\": {" reply.content += "\"route_summary\": {"
"\"total_distance\":"; "\"total_distance\":";
reply.content += summary.lengthString; reply.content += summary.lengthString;
reply.content += "," reply.content += ","
"\"total_time\":"; "\"total_time\":";
reply.content += summary.durationString; reply.content += summary.durationString;
reply.content += "," reply.content += ","
"\"start_point\":\""; "\"start_point\":\"";
reply.content += summary.startName; reply.content += summary.startName;
reply.content += "\"," reply.content += "\","
"\"end_point\":\""; "\"end_point\":\"";
reply.content += summary.destName; reply.content += summary.destName;
reply.content += "\""; reply.content += "\"";
reply.content += "},"; reply.content += "},";
reply.content += "\"route_geometry\": "; reply.content += "\"route_geometry\": ";
if(config.geometry) { if(config.geometry) {
if(config.encodeGeometry) if(config.encodeGeometry)
descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry); descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
} else { } else {
reply.content += "[]"; reply.content += "[]";
} }
reply.content += "," reply.content += ","
"\"route_instructions\": ["; "\"route_instructions\": [";
if(config.instructions) { if(config.instructions) {
//Segment information has following format: //Segment information has following format:
//["instruction","streetname",length,position,time,"length","earth_direction",azimuth] //["instruction","streetname",length,position,time,"length","earth_direction",azimuth]
//Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5] //Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5]
//See also: http://developers.cloudmade.com/wiki/navengine/JSON_format //See also: http://developers.cloudmade.com/wiki/navengine/JSON_format
unsigned prefixSumOfNecessarySegments = 0; unsigned prefixSumOfNecessarySegments = 0;
roundAbout.leaveAtExit = 0; roundAbout.leaveAtExit = 0;
roundAbout.nameID = 0; roundAbout.nameID = 0;
std::string tmpDist, tmpLength, tmp; std::string tmpDist, tmpLength, tmpDuration;
//Fetch data from Factory and generate a string from it. //Fetch data from Factory and generate a string from it.
BOOST_FOREACH(SegmentInformation segment, descriptionFactory.pathDescription) { BOOST_FOREACH(SegmentInformation & segment, descriptionFactory.pathDescription) {
if(TurnInstructions.TurnIsNecessary( segment.turnInstruction) ) { if(TurnInstructions.TurnIsNecessary( segment.turnInstruction) ) {
if(TurnInstructions.EnterRoundAbout == segment.turnInstruction) { if(TurnInstructions.EnterRoundAbout == segment.turnInstruction) {
roundAbout.nameID = segment.nameID; roundAbout.nameID = segment.nameID;
roundAbout.startIndex = prefixSumOfNecessarySegments; roundAbout.startIndex = prefixSumOfNecessarySegments;
} else { } else {
if(0 != prefixSumOfNecessarySegments) if(0 != prefixSumOfNecessarySegments)
reply.content += ","; reply.content += ",";
reply.content += "[\""; reply.content += "[\"";
if(TurnInstructions.LeaveRoundAbout == segment.turnInstruction) { if(TurnInstructions.LeaveRoundAbout == segment.turnInstruction) {
reply.content += TurnInstructions.TurnStrings[TurnInstructions.EnterRoundAbout]; reply.content += TurnInstructions.TurnStrings[TurnInstructions.EnterRoundAbout];
reply.content += " and leave at "; reply.content += " and leave at ";
reply.content += TurnInstructions.Ordinals[roundAbout.leaveAtExit+1]; reply.content += TurnInstructions.Ordinals[roundAbout.leaveAtExit+1];
reply.content += " exit"; reply.content += " exit";
roundAbout.leaveAtExit = 0; roundAbout.leaveAtExit = 0;
} else { } else {
reply.content += TurnInstructions.TurnStrings[segment.turnInstruction]; reply.content += TurnInstructions.TurnStrings[segment.turnInstruction];
} }
reply.content += "\",\""; reply.content += "\",\"";
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID); reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
reply.content += "\","; reply.content += "\",";
intToString(segment.length, tmpDist); intToString(segment.length, tmpDist);
reply.content += tmpDist; reply.content += tmpDist;
reply.content += ","; reply.content += ",";
intToString(prefixSumOfNecessarySegments, tmpLength); intToString(prefixSumOfNecessarySegments, tmpLength);
reply.content += tmpLength; reply.content += tmpLength;
reply.content += ","; reply.content += ",";
intToString(segment.duration, tmp); intToString(segment.duration, tmpDuration);
reply.content += ",\""; reply.content += tmpDuration;
reply.content += tmpLength; reply.content += ",\"";
//TODO: fix heading reply.content += tmpLength;
reply.content += "\",\"NE\",22.5"; //TODO: fix heading
reply.content += "]"; reply.content += "\",\"NE\",22.5";
} reply.content += "]";
} else if(TurnInstructions.StayOnRoundAbout == segment.turnInstruction) { }
++roundAbout.leaveAtExit; } else if(TurnInstructions.StayOnRoundAbout == segment.turnInstruction) {
} ++roundAbout.leaveAtExit;
if(segment.necessary) }
++prefixSumOfNecessarySegments; if(segment.necessary)
} ++prefixSumOfNecessarySegments;
} }
reply.content += "],"; }
//list all viapoints so that the client may display it reply.content += "],";
reply.content += "\"via_points\":["; //list all viapoints so that the client may display it
for(unsigned segmentIdx = 1; (true == config.geometry) && (segmentIdx < rawRoute.segmentEndCoordinates.size()); segmentIdx++) { reply.content += "\"via_points\":[";
if(segmentIdx > 1) if(true == config.geometry) {
reply.content += ","; std::string tmp;
reply.content += "["; for(unsigned segmentIdx = 1; segmentIdx < rawRoute.segmentEndCoordinates.size(); ++segmentIdx) {
if(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location.isSet()) if(segmentIdx > 1)
convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location, tmp); reply.content += ",";
else reply.content += "[";
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates[segmentIdx], tmp); if(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location.isSet())
reply.content += tmp; convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location, tmp);
reply.content += "]"; else
} convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates[segmentIdx], tmp);
reply.content += "]," reply.content += tmp;
"\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.2)\""; reply.content += "]";
reply.content += "}"; }
} }
reply.content += "],"
"\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"";
reply.content += "}";
}
void WriteHeaderToOutput(std::string & output) { inline void WriteHeaderToOutput(std::string & output) {
output += "{" output += "{"
"\"version\": 0.3," "\"version\": 0.3,"
"\"status\":"; "\"status\":";
} }
}; };
#endif /* JSON_DESCRIPTOR_H_ */ #endif /* JSON_DESCRIPTOR_H_ */