Fixes issue #202
This commit is contained in:
parent
2549f7254a
commit
e4080aba05
@ -34,167 +34,168 @@ 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;
|
||||||
DescriptionFactory descriptionFactory;
|
DescriptionFactory descriptionFactory;
|
||||||
_Coordinate current;
|
_Coordinate current;
|
||||||
unsigned numberOfEnteredRestrictedAreas;
|
unsigned numberOfEnteredRestrictedAreas;
|
||||||
struct {
|
struct {
|
||||||
int startIndex;
|
int startIndex;
|
||||||
int nameID;
|
int nameID;
|
||||||
int leaveAtExit;
|
int leaveAtExit;
|
||||||
} roundAbout;
|
} roundAbout;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JSONDescriptor() : numberOfEnteredRestrictedAreas(0) {}
|
JSONDescriptor() : numberOfEnteredRestrictedAreas(0) {}
|
||||||
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, const 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) {
|
if(durationOfTrip != INT_MAX) {
|
||||||
descriptionFactory.SetStartSegment(phantomNodes.startPhantom);
|
descriptionFactory.SetStartSegment(phantomNodes.startPhantom);
|
||||||
reply.content += "0,"
|
reply.content += "0,"
|
||||||
"\"status_message\": \"Found route between points\",";
|
"\"status_message\": \"Found route between points\",";
|
||||||
|
|
||||||
//Get all the coordinates for the computed route
|
//Get all the coordinates for the computed route
|
||||||
BOOST_FOREACH(_PathData & pathData, rawRoute.computedRouted) {
|
BOOST_FOREACH(_PathData & pathData, rawRoute.computedRouted) {
|
||||||
sEngine.GetCoordinatesForNodeID(pathData.node, current);
|
sEngine.GetCoordinatesForNodeID(pathData.node, current);
|
||||||
descriptionFactory.AppendSegment(current, pathData );
|
descriptionFactory.AppendSegment(current, pathData );
|
||||||
}
|
}
|
||||||
descriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
|
descriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
|
||||||
} else {
|
} else {
|
||||||
//We do not need to do much, if there is no route ;-)
|
//We do not need to do much, if there is no route ;-)
|
||||||
reply.content += "207,"
|
reply.content += "207,"
|
||||||
"\"status_message\": \"Cannot find route between points\",";
|
"\"status_message\": \"Cannot find route between points\",";
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptionFactory.Run(sEngine, config.z, durationOfTrip);
|
descriptionFactory.Run(sEngine, config.z, durationOfTrip);
|
||||||
reply.content += "\"route_geometry\": ";
|
reply.content += "\"route_geometry\": ";
|
||||||
if(config.geometry) {
|
if(config.geometry) {
|
||||||
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, tmpDuration, tmpBearing;
|
std::string tmpDist, tmpLength, tmpDuration, tmpBearing;
|
||||||
//Fetch data from Factory and generate a string from it.
|
//Fetch data from Factory and generate a string from it.
|
||||||
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
||||||
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
||||||
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
|
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
|
||||||
if(TurnInstructions.TurnIsNecessary( currentInstruction) ) {
|
if(TurnInstructions.TurnIsNecessary( currentInstruction) ) {
|
||||||
if(TurnInstructions.EnterRoundAbout == currentInstruction) {
|
if(TurnInstructions.EnterRoundAbout == currentInstruction) {
|
||||||
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 == currentInstruction) {
|
if(TurnInstructions.LeaveRoundAbout == currentInstruction) {
|
||||||
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[std::min(11,roundAbout.leaveAtExit+1)];
|
reply.content += TurnInstructions.Ordinals[std::min(11,roundAbout.leaveAtExit+1)];
|
||||||
reply.content += " exit";
|
reply.content += " exit";
|
||||||
roundAbout.leaveAtExit = 0;
|
roundAbout.leaveAtExit = 0;
|
||||||
} else {
|
} else {
|
||||||
reply.content += TurnInstructions.TurnStrings[currentInstruction];
|
reply.content += TurnInstructions.TurnStrings[currentInstruction];
|
||||||
}
|
}
|
||||||
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, tmpDuration);
|
intToString(segment.duration, tmpDuration);
|
||||||
reply.content += tmpDuration;
|
reply.content += tmpDuration;
|
||||||
reply.content += ",\"";
|
reply.content += ",\"";
|
||||||
intToString(segment.length, tmpLength);
|
intToString(segment.length, tmpLength);
|
||||||
reply.content += tmpLength;
|
reply.content += tmpLength;
|
||||||
reply.content += "m\",\"";
|
reply.content += "m\",\"";
|
||||||
reply.content += Azimuth::Get(segment.bearing);
|
reply.content += Azimuth::Get(segment.bearing);
|
||||||
reply.content += "\",";
|
reply.content += "\",";
|
||||||
doubleToStringWithTwoDigitsBehindComma(segment.bearing, tmpBearing);
|
doubleToStringWithTwoDigitsBehindComma(segment.bearing, tmpBearing);
|
||||||
reply.content += tmpBearing;
|
reply.content += tmpBearing;
|
||||||
reply.content += "]";
|
reply.content += "]";
|
||||||
}
|
}
|
||||||
} else if(TurnInstructions.StayOnRoundAbout == currentInstruction) {
|
} else if(TurnInstructions.StayOnRoundAbout == currentInstruction) {
|
||||||
++roundAbout.leaveAtExit;
|
++roundAbout.leaveAtExit;
|
||||||
}
|
}
|
||||||
if(segment.necessary)
|
if(segment.necessary)
|
||||||
++prefixSumOfNecessarySegments;
|
++prefixSumOfNecessarySegments;
|
||||||
}
|
}
|
||||||
|
if(durationOfTrip != INT_MAX) {
|
||||||
reply.content += ",[\"";
|
reply.content += ",[\"";
|
||||||
reply.content += TurnInstructions.TurnStrings[TurnInstructions.ReachedYourDestination];
|
reply.content += TurnInstructions.TurnStrings[TurnInstructions.ReachedYourDestination];
|
||||||
reply.content += "\",\"";
|
reply.content += "\",\"";
|
||||||
reply.content += "\",";
|
reply.content += "\",";
|
||||||
reply.content += "0";
|
reply.content += "0";
|
||||||
reply.content += ",";
|
reply.content += ",";
|
||||||
intToString(prefixSumOfNecessarySegments-1, tmpLength);
|
intToString(prefixSumOfNecessarySegments-1, tmpLength);
|
||||||
reply.content += tmpLength;
|
reply.content += tmpLength;
|
||||||
reply.content += ",";
|
reply.content += ",";
|
||||||
reply.content += "0";
|
reply.content += "0";
|
||||||
reply.content += ",\"";
|
reply.content += ",\"";
|
||||||
reply.content += "\",\"";
|
reply.content += "\",\"";
|
||||||
reply.content += Azimuth::Get(0.0);
|
reply.content += Azimuth::Get(0.0);
|
||||||
reply.content += "\",";
|
reply.content += "\",";
|
||||||
reply.content += "0.0";
|
reply.content += "0.0";
|
||||||
reply.content += "]";
|
reply.content += "]";
|
||||||
} else {
|
}
|
||||||
|
} else {
|
||||||
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
||||||
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
||||||
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
|
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reply.content += "],";
|
reply.content += "],";
|
||||||
// INFO("Entered " << numberOfEnteredRestrictedAreas << " restricted areas");
|
// INFO("Entered " << numberOfEnteredRestrictedAreas << " restricted areas");
|
||||||
descriptionFactory.BuildRouteSummary(descriptionFactory.entireLength, durationOfTrip - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenaly));
|
descriptionFactory.BuildRouteSummary(descriptionFactory.entireLength, durationOfTrip - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenaly));
|
||||||
|
|
||||||
reply.content += "\"route_summary\": {"
|
reply.content += "\"route_summary\": {"
|
||||||
"\"total_distance\":";
|
"\"total_distance\":";
|
||||||
reply.content += descriptionFactory.summary.lengthString;
|
reply.content += descriptionFactory.summary.lengthString;
|
||||||
reply.content += ","
|
reply.content += ","
|
||||||
"\"total_time\":";
|
"\"total_time\":";
|
||||||
reply.content += descriptionFactory.summary.durationString;
|
reply.content += descriptionFactory.summary.durationString;
|
||||||
reply.content += ","
|
reply.content += ","
|
||||||
"\"start_point\":\"";
|
"\"start_point\":\"";
|
||||||
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName);
|
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName);
|
||||||
reply.content += "\","
|
reply.content += "\","
|
||||||
"\"end_point\":\"";
|
"\"end_point\":\"";
|
||||||
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
|
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
|
||||||
reply.content += "\"";
|
reply.content += "\"";
|
||||||
reply.content += "},";
|
reply.content += "},";
|
||||||
|
|
||||||
//list all viapoints so that the client may display it
|
//list all viapoints so that the client may display it
|
||||||
reply.content += "\"via_points\":[";
|
reply.content += "\"via_points\":[";
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
if(true == config.geometry) {
|
if(true == config.geometry) {
|
||||||
for(unsigned segmentIdx = 1; segmentIdx < rawRoute.segmentEndCoordinates.size(); ++segmentIdx) {
|
for(unsigned segmentIdx = 1; segmentIdx < rawRoute.segmentEndCoordinates.size(); ++segmentIdx) {
|
||||||
if(segmentIdx > 1)
|
if(segmentIdx > 1)
|
||||||
reply.content += ",";
|
reply.content += ",";
|
||||||
reply.content += "[";
|
reply.content += "[";
|
||||||
if(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location.isSet())
|
if(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location.isSet())
|
||||||
convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location, tmp);
|
convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location, tmp);
|
||||||
else
|
else
|
||||||
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates[segmentIdx], tmp);
|
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates[segmentIdx], tmp);
|
||||||
|
|
||||||
reply.content += tmp;
|
reply.content += tmp;
|
||||||
reply.content += "]";
|
reply.content += "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reply.content += "],";
|
reply.content += "],";
|
||||||
reply.content += "\"hint_data\": {";
|
reply.content += "\"hint_data\": {";
|
||||||
reply.content += "\"checksum\":";
|
reply.content += "\"checksum\":";
|
||||||
intToString(rawRoute.checkSum, tmp);
|
intToString(rawRoute.checkSum, tmp);
|
||||||
@ -214,14 +215,14 @@ public:
|
|||||||
reply.content += hint;
|
reply.content += hint;
|
||||||
reply.content += "\"]";
|
reply.content += "\"]";
|
||||||
reply.content += "},";
|
reply.content += "},";
|
||||||
reply.content += "\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"";
|
reply.content += "\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"";
|
||||||
reply.content += "}";
|
reply.content += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline 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_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user