explicitly give the locations of all via locations in response
This commit is contained in:
@@ -61,10 +61,10 @@ public:
|
||||
//Maybe someone can explain the pure virtual destructor thing to me (dennis)
|
||||
virtual ~BaseDescriptor() { }
|
||||
virtual void Run(
|
||||
http::Reply & reply,
|
||||
const RawRouteData &rawRoute,
|
||||
PhantomNodes &phantomNodes,
|
||||
const DataFacadeT * facade
|
||||
const RawRouteData & rawRoute,
|
||||
const PhantomNodes & phantomNodes,
|
||||
DataFacadeT * facade,
|
||||
http::Reply & reply
|
||||
) = 0;
|
||||
virtual void SetConfig(const DescriptorConfig & config) = 0;
|
||||
};
|
||||
|
||||
@@ -43,13 +43,13 @@ double DescriptionFactory::GetBearing(
|
||||
const FixedPointCoordinate & A,
|
||||
const FixedPointCoordinate & B
|
||||
) const {
|
||||
double deltaLong = DegreeToRadian(B.lon/COORDINATE_PRECISION - A.lon/COORDINATE_PRECISION);
|
||||
double delta_long = DegreeToRadian(B.lon/COORDINATE_PRECISION - A.lon/COORDINATE_PRECISION);
|
||||
|
||||
const double lat1 = DegreeToRadian(A.lat/COORDINATE_PRECISION);
|
||||
const double lat2 = DegreeToRadian(B.lat/COORDINATE_PRECISION);
|
||||
|
||||
const double y = sin(deltaLong) * cos(lat2);
|
||||
const double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong);
|
||||
const double y = sin(delta_long) * cos(lat2);
|
||||
const double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_long);
|
||||
double result = RadianToDegree(atan2(y, x));
|
||||
while(result < 0.) {
|
||||
result += 360.;
|
||||
@@ -60,22 +60,22 @@ double DescriptionFactory::GetBearing(
|
||||
return result;
|
||||
}
|
||||
|
||||
void DescriptionFactory::SetStartSegment(const PhantomNode & sph) {
|
||||
start_phantom = sph;
|
||||
void DescriptionFactory::SetStartSegment(const PhantomNode & start) {
|
||||
start_phantom = start;
|
||||
AppendSegment(
|
||||
sph.location,
|
||||
PathData(0, sph.nodeBasedEdgeNameID, 10, sph.weight1)
|
||||
start.location,
|
||||
PathData(0, start.nodeBasedEdgeNameID, 10, start.weight1)
|
||||
);
|
||||
}
|
||||
|
||||
void DescriptionFactory::SetEndSegment(const PhantomNode & tph) {
|
||||
target_phantom = tph;
|
||||
void DescriptionFactory::SetEndSegment(const PhantomNode & target) {
|
||||
target_phantom = target;
|
||||
pathDescription.push_back(
|
||||
SegmentInformation(
|
||||
tph.location,
|
||||
tph.nodeBasedEdgeNameID,
|
||||
target.location,
|
||||
target.nodeBasedEdgeNameID,
|
||||
0,
|
||||
tph.weight1,
|
||||
target.weight1,
|
||||
0,
|
||||
true
|
||||
)
|
||||
@@ -86,10 +86,21 @@ void DescriptionFactory::AppendSegment(
|
||||
const FixedPointCoordinate & coordinate,
|
||||
const PathData & data
|
||||
) {
|
||||
if(1 == pathDescription.size() && pathDescription.back().location == coordinate) {
|
||||
if(
|
||||
( 1 == pathDescription.size()) &&
|
||||
( pathDescription.back().location == coordinate)
|
||||
) {
|
||||
pathDescription.back().name_id = data.name_id;
|
||||
} else {
|
||||
pathDescription.push_back(SegmentInformation(coordinate, data.name_id, 0, data.durationOfSegment, data.turnInstruction) );
|
||||
pathDescription.push_back(
|
||||
SegmentInformation(
|
||||
coordinate,
|
||||
data.name_id,
|
||||
0,
|
||||
data.durationOfSegment,
|
||||
data.turnInstruction
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,127 +133,6 @@ void DescriptionFactory::AppendUnencodedPolylineString(
|
||||
output.push_back(temp);
|
||||
}
|
||||
|
||||
// void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLevel) {
|
||||
|
||||
// if(0 == pathDescription.size())
|
||||
// return;
|
||||
|
||||
// // unsigned entireLength = 0;
|
||||
// /** starts at index 1 */
|
||||
// pathDescription[0].length = 0;
|
||||
// for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
||||
// pathDescription[i].length = ApproximateEuclideanDistance(pathDescription[i-1].location, pathDescription[i].location);
|
||||
// }
|
||||
|
||||
// double lengthOfSegment = 0;
|
||||
// unsigned durationOfSegment = 0;
|
||||
// unsigned indexOfSegmentBegin = 0;
|
||||
|
||||
// std::string string0 = sEngine.GetEscapedNameForNameID(pathDescription[0].name_id);
|
||||
// std::string string1;
|
||||
|
||||
|
||||
// /*Simplify turn instructions
|
||||
// Input :
|
||||
// 10. Turn left on B 36 for 20 km
|
||||
// 11. Continue on B 35; B 36 for 2 km
|
||||
// 12. Continue on B 36 for 13 km
|
||||
|
||||
// becomes:
|
||||
// 10. Turn left on B 36 for 35 km
|
||||
// */
|
||||
// //TODO: rework to check only end and start of string.
|
||||
// // stl string is way to expensive
|
||||
|
||||
// // unsigned lastTurn = 0;
|
||||
// // for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
||||
// // string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].name_id);
|
||||
// // if(TurnInstructionsClass::GoStraight == pathDescription[i].turnInstruction) {
|
||||
// // if(std::string::npos != string0.find(string1+";")
|
||||
// // || std::string::npos != string0.find(";"+string1)
|
||||
// // || std::string::npos != string0.find(string1+" ;")
|
||||
// // || std::string::npos != string0.find("; "+string1)
|
||||
// // ){
|
||||
// // SimpleLogger().Write() << "->next correct: " << string0 << " contains " << string1;
|
||||
// // for(; lastTurn != i; ++lastTurn)
|
||||
// // pathDescription[lastTurn].name_id = pathDescription[i].name_id;
|
||||
// // pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
|
||||
// // } else if(std::string::npos != string1.find(string0+";")
|
||||
// // || std::string::npos != string1.find(";"+string0)
|
||||
// // || std::string::npos != string1.find(string0+" ;")
|
||||
// // || std::string::npos != string1.find("; "+string0)
|
||||
// // ){
|
||||
// // SimpleLogger().Write() << "->prev correct: " << string1 << " contains " << string0;
|
||||
// // pathDescription[i].name_id = pathDescription[i-1].name_id;
|
||||
// // pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
|
||||
// // }
|
||||
// // }
|
||||
// // if (TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
|
||||
// // lastTurn = i;
|
||||
// // }
|
||||
// // string0 = string1;
|
||||
// // }
|
||||
|
||||
|
||||
// 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(TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
|
||||
// //SimpleLogger().Write() << "Turn after " << lengthOfSegment << "m into way with name id " << segment.name_id;
|
||||
// assert(pathDescription[i].necessary);
|
||||
// lengthOfSegment = 0;
|
||||
// durationOfSegment = 0;
|
||||
// indexOfSegmentBegin = i;
|
||||
// }
|
||||
// }
|
||||
// // SimpleLogger().Write() << "#segs: " << pathDescription.size();
|
||||
|
||||
// //Post-processing to remove empty or nearly empty path segments
|
||||
// if(FLT_EPSILON > pathDescription.back().length) {
|
||||
// // SimpleLogger().Write() << "#segs: " << pathDescription.size() << ", last ratio: " << target_phantom.ratio << ", length: " << pathDescription.back().length;
|
||||
// if(pathDescription.size() > 2){
|
||||
// pathDescription.pop_back();
|
||||
// pathDescription.back().necessary = true;
|
||||
// pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
|
||||
// target_phantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->name_id;
|
||||
// // SimpleLogger().Write() << "Deleting last turn instruction";
|
||||
// }
|
||||
// } else {
|
||||
// pathDescription[indexOfSegmentBegin].duration *= (1.-target_phantom.ratio);
|
||||
// }
|
||||
// if(FLT_EPSILON > pathDescription[0].length) {
|
||||
// //TODO: this is never called actually?
|
||||
// if(pathDescription.size() > 2) {
|
||||
// pathDescription.erase(pathDescription.begin());
|
||||
// pathDescription[0].turnInstruction = TurnInstructions.HeadOn;
|
||||
// pathDescription[0].necessary = true;
|
||||
// start_phantom.nodeBasedEdgeNameID = pathDescription[0].name_id;
|
||||
// // SimpleLogger().Write() << "Deleting first turn instruction, ratio: " << start_phantom.ratio << ", length: " << pathDescription[0].length;
|
||||
// }
|
||||
// } else {
|
||||
// pathDescription[0].duration *= start_phantom.ratio;
|
||||
// }
|
||||
|
||||
// //Generalize poly line
|
||||
// dp.Run(pathDescription, zoomLevel);
|
||||
|
||||
// //fix what needs to be fixed else
|
||||
// for(unsigned i = 0; i < pathDescription.size()-1 && pathDescription.size() >= 2; ++i){
|
||||
// if(pathDescription[i].necessary) {
|
||||
// double angle = GetBearing(pathDescription[i].location, pathDescription[i+1].location);
|
||||
// pathDescription[i].bearing = angle;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // BuildRouteSummary(entireLength, duration);
|
||||
// return;
|
||||
// }
|
||||
|
||||
void DescriptionFactory::BuildRouteSummary(
|
||||
const double distance,
|
||||
const unsigned time
|
||||
|
||||
@@ -91,11 +91,13 @@ public:
|
||||
void AppendEncodedPolylineString(
|
||||
const bool return_encoded,
|
||||
std::vector<std::string> & output
|
||||
);
|
||||
);
|
||||
|
||||
template<class DataFacadeT>
|
||||
void Run(const DataFacadeT * facade, const unsigned zoomLevel) {
|
||||
|
||||
void Run(
|
||||
const DataFacadeT * facade,
|
||||
const unsigned zoomLevel
|
||||
) {
|
||||
if( pathDescription.empty() ) {
|
||||
return;
|
||||
}
|
||||
@@ -107,10 +109,6 @@ public:
|
||||
pathDescription[i].length = ApproximateEuclideanDistance(pathDescription[i-1].location, pathDescription[i].location);
|
||||
}
|
||||
|
||||
double lengthOfSegment = 0;
|
||||
unsigned durationOfSegment = 0;
|
||||
unsigned indexOfSegmentBegin = 0;
|
||||
|
||||
// std::string string0 = facade->GetEscapedNameForNameID(pathDescription[0].name_id);
|
||||
// std::string string1;
|
||||
|
||||
@@ -156,6 +154,9 @@ public:
|
||||
// string0 = string1;
|
||||
// }
|
||||
|
||||
double lengthOfSegment = 0;
|
||||
unsigned durationOfSegment = 0;
|
||||
unsigned indexOfSegmentBegin = 0;
|
||||
|
||||
for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
||||
entireLength += pathDescription[i].length;
|
||||
@@ -183,7 +184,7 @@ public:
|
||||
pathDescription.back().necessary = true;
|
||||
pathDescription.back().turn_instruction = TurnInstructions.NoTurn;
|
||||
target_phantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->name_id;
|
||||
// SimpleLogger().Write() << "Deleting last turn instruction";
|
||||
SimpleLogger().Write() << "Deleting last turn instruction";
|
||||
}
|
||||
} else {
|
||||
pathDescription[indexOfSegmentBegin].duration *= (1.-target_phantom.ratio);
|
||||
|
||||
+28
-25
@@ -44,10 +44,10 @@ public:
|
||||
|
||||
//TODO: reorder parameters
|
||||
void Run(
|
||||
http::Reply & reply,
|
||||
const RawRouteData &rawRoute,
|
||||
PhantomNodes &phantomNodes,
|
||||
const DataFacadeT * facade
|
||||
const RawRouteData &raw_route,
|
||||
const PhantomNodes &phantom_node_list,
|
||||
DataFacadeT * facade,
|
||||
http::Reply & reply
|
||||
) {
|
||||
reply.content.push_back("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
reply.content.push_back(
|
||||
@@ -61,41 +61,44 @@ public:
|
||||
" OpenStreetMap contributors (ODbL)</license></copyright>"
|
||||
"</metadata>");
|
||||
reply.content.push_back("<rte>");
|
||||
bool found_route = (rawRoute.lengthOfShortestPath != INT_MAX) &&
|
||||
(rawRoute.computedShortestPath.size() );
|
||||
bool found_route = (raw_route.lengthOfShortestPath != INT_MAX) &&
|
||||
(raw_route.unpacked_path_segments[0].size());
|
||||
if( found_route ) {
|
||||
convertInternalLatLonToString(
|
||||
phantomNodes.startPhantom.location.lat,
|
||||
phantom_node_list.startPhantom.location.lat,
|
||||
tmp
|
||||
);
|
||||
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
|
||||
convertInternalLatLonToString(
|
||||
phantomNodes.startPhantom.location.lon,
|
||||
phantom_node_list.startPhantom.location.lon,
|
||||
tmp
|
||||
);
|
||||
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
|
||||
|
||||
BOOST_FOREACH(
|
||||
const PathData & pathData,
|
||||
rawRoute.computedShortestPath
|
||||
) {
|
||||
current = facade->GetCoordinateOfNode(pathData.node);
|
||||
for(unsigned i=0; i < raw_route.unpacked_path_segments.size(); ++i){
|
||||
BOOST_FOREACH(
|
||||
const PathData & pathData,
|
||||
raw_route.unpacked_path_segments[i]
|
||||
) {
|
||||
current = facade->GetCoordinateOfNode(pathData.node);
|
||||
|
||||
convertInternalLatLonToString(current.lat, tmp);
|
||||
convertInternalLatLonToString(current.lat, tmp);
|
||||
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
|
||||
convertInternalLatLonToString(current.lon, tmp);
|
||||
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
|
||||
}
|
||||
// TODO: Add the via point or the end coordinate
|
||||
convertInternalLatLonToString(
|
||||
phantom_node_list.targetPhantom.location.lat,
|
||||
tmp
|
||||
);
|
||||
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
|
||||
convertInternalLatLonToString(current.lon, tmp);
|
||||
convertInternalLatLonToString(
|
||||
phantom_node_list.targetPhantom.location.lon,
|
||||
tmp
|
||||
);
|
||||
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
|
||||
}
|
||||
convertInternalLatLonToString(
|
||||
phantomNodes.targetPhantom.location.lat,
|
||||
tmp
|
||||
);
|
||||
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
|
||||
convertInternalLatLonToString(
|
||||
phantomNodes.targetPhantom.location.lon,
|
||||
tmp
|
||||
);
|
||||
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
|
||||
}
|
||||
reply.content.push_back("</rte></gpx>");
|
||||
}
|
||||
|
||||
+123
-84
@@ -44,9 +44,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
template<class DataFacadeT>
|
||||
class JSONDescriptor : public BaseDescriptor<DataFacadeT> {
|
||||
private:
|
||||
DataFacadeT * facade;
|
||||
DescriptorConfig config;
|
||||
DescriptionFactory description_factory;
|
||||
DescriptionFactory alternateDescriptionFactory;
|
||||
DescriptionFactory alternate_descriptionFactory;
|
||||
FixedPointCoordinate current;
|
||||
unsigned entered_restricted_area_count;
|
||||
struct RoundAbout{
|
||||
@@ -68,6 +69,7 @@ private:
|
||||
int position;
|
||||
};
|
||||
std::vector<Segment> shortest_path_segments, alternative_path_segments;
|
||||
std::vector<unsigned> shortest_leg_end_indices, alternative_leg_end_indices;
|
||||
|
||||
struct RouteNames {
|
||||
std::string shortestPathName1;
|
||||
@@ -77,37 +79,68 @@ private:
|
||||
};
|
||||
|
||||
public:
|
||||
JSONDescriptor() : entered_restricted_area_count(0) {}
|
||||
JSONDescriptor() : entered_restricted_area_count(0) {
|
||||
shortest_leg_end_indices.push_back(0);
|
||||
alternative_leg_end_indices.push_back(0);
|
||||
}
|
||||
|
||||
void SetConfig(const DescriptorConfig & c) { config = c; }
|
||||
|
||||
//TODO: reorder parameters
|
||||
void Run(
|
||||
http::Reply & reply,
|
||||
const RawRouteData & raw_route_information,
|
||||
PhantomNodes & phantom_nodes,
|
||||
const DataFacadeT * facade
|
||||
int DescribeLeg(
|
||||
const std::vector<PathData> route_leg,
|
||||
const PhantomNodes & leg_phantoms
|
||||
) {
|
||||
int added_element_count = 0;
|
||||
//Get all the coordinates for the computed route
|
||||
FixedPointCoordinate current_coordinate;
|
||||
BOOST_FOREACH(const PathData & path_data, route_leg) {
|
||||
current_coordinate = facade->GetCoordinateOfNode(path_data.node);
|
||||
description_factory.AppendSegment(current_coordinate, path_data );
|
||||
++added_element_count;
|
||||
}
|
||||
// description_factory.SetEndSegment( leg_phantoms.targetPhantom );
|
||||
++added_element_count;
|
||||
BOOST_ASSERT( route_leg.size() + 1 == added_element_count );
|
||||
return added_element_count;
|
||||
}
|
||||
|
||||
WriteHeaderToOutput(reply.content);
|
||||
void Run(
|
||||
const RawRouteData & raw_route,
|
||||
const PhantomNodes & phantom_nodes,
|
||||
// TODO: move facade initalization to c'tor
|
||||
DataFacadeT * f,
|
||||
http::Reply & reply
|
||||
) {
|
||||
facade = f;
|
||||
reply.content.push_back(
|
||||
"{\"status\":"
|
||||
);
|
||||
|
||||
if(raw_route_information.lengthOfShortestPath != INT_MAX) {
|
||||
if(raw_route.lengthOfShortestPath != INT_MAX) {
|
||||
description_factory.SetStartSegment(phantom_nodes.startPhantom);
|
||||
reply.content.push_back("0,"
|
||||
"\"status_message\": \"Found route between points\",");
|
||||
|
||||
//Get all the coordinates for the computed route
|
||||
BOOST_FOREACH(const PathData & path_data, raw_route_information.computedShortestPath) {
|
||||
current = facade->GetCoordinateOfNode(path_data.node);
|
||||
description_factory.AppendSegment(current, path_data );
|
||||
BOOST_ASSERT( raw_route.unpacked_path_segments.size() == raw_route.segmentEndCoordinates.size() );
|
||||
for( unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i ) {
|
||||
const int added_segments = DescribeLeg(
|
||||
raw_route.unpacked_path_segments[i],
|
||||
raw_route.segmentEndCoordinates[i]
|
||||
);
|
||||
BOOST_ASSERT( 0 < added_segments );
|
||||
shortest_leg_end_indices.push_back(
|
||||
added_segments + shortest_leg_end_indices.back()
|
||||
);
|
||||
}
|
||||
description_factory.SetEndSegment(phantom_nodes.targetPhantom);
|
||||
description_factory.Run(facade, config.zoom_level);
|
||||
} else {
|
||||
//We do not need to do much, if there is no route ;-)
|
||||
reply.content.push_back("207,"
|
||||
"\"status_message\": \"Cannot find route between points\",");
|
||||
"\"status_message\": \"Cannot find route between points\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
description_factory.Run(facade, config.zoom_level);
|
||||
reply.content.push_back("\"route_geometry\": ");
|
||||
if(config.geometry) {
|
||||
description_factory.AppendEncodedPolylineString(
|
||||
@@ -118,30 +151,20 @@ public:
|
||||
reply.content.push_back("[]");
|
||||
}
|
||||
|
||||
reply.content.push_back(","
|
||||
"\"route_instructions\": [");
|
||||
entered_restricted_area_count = 0;
|
||||
reply.content.push_back(",\"route_instructions\": [");
|
||||
if(config.instructions) {
|
||||
BuildTextualDescription(
|
||||
description_factory,
|
||||
reply,
|
||||
raw_route_information.lengthOfShortestPath,
|
||||
raw_route.lengthOfShortestPath,
|
||||
facade,
|
||||
shortest_path_segments
|
||||
);
|
||||
} else {
|
||||
BOOST_FOREACH(
|
||||
const SegmentInformation & segment,
|
||||
description_factory.pathDescription
|
||||
) {
|
||||
TurnInstruction current_instruction = segment.turn_instruction & TurnInstructions.InverseAccessRestrictionFlag;
|
||||
entered_restricted_area_count += (current_instruction != segment.turn_instruction);
|
||||
}
|
||||
}
|
||||
reply.content.push_back("],");
|
||||
description_factory.BuildRouteSummary(
|
||||
description_factory.entireLength,
|
||||
raw_route_information.lengthOfShortestPath - ( entered_restricted_area_count*TurnInstructions.AccessRestrictionPenalty)
|
||||
raw_route.lengthOfShortestPath
|
||||
);
|
||||
|
||||
reply.content.push_back("\"route_summary\":");
|
||||
@@ -167,62 +190,67 @@ public:
|
||||
|
||||
//only one alternative route is computed at this time, so this is hardcoded
|
||||
|
||||
if(raw_route_information.lengthOfAlternativePath != INT_MAX) {
|
||||
alternateDescriptionFactory.SetStartSegment(phantom_nodes.startPhantom);
|
||||
if(raw_route.lengthOfAlternativePath != INT_MAX) {
|
||||
alternate_descriptionFactory.SetStartSegment(phantom_nodes.startPhantom);
|
||||
//Get all the coordinates for the computed route
|
||||
BOOST_FOREACH(const PathData & path_data, raw_route_information.computedAlternativePath) {
|
||||
BOOST_FOREACH(const PathData & path_data, raw_route.unpacked_alternative) {
|
||||
current = facade->GetCoordinateOfNode(path_data.node);
|
||||
alternateDescriptionFactory.AppendSegment(current, path_data );
|
||||
alternate_descriptionFactory.AppendSegment(current, path_data );
|
||||
}
|
||||
alternateDescriptionFactory.SetEndSegment(phantom_nodes.targetPhantom);
|
||||
alternate_descriptionFactory.SetEndSegment(phantom_nodes.targetPhantom);
|
||||
}
|
||||
alternateDescriptionFactory.Run(facade, config.zoom_level);
|
||||
alternate_descriptionFactory.Run(facade, config.zoom_level);
|
||||
|
||||
//give an array of alternative routes
|
||||
// //give an array of alternative routes
|
||||
reply.content.push_back("\"alternative_geometries\": [");
|
||||
if(config.geometry && INT_MAX != raw_route_information.lengthOfAlternativePath) {
|
||||
if(config.geometry && INT_MAX != raw_route.lengthOfAlternativePath) {
|
||||
//Generate the linestrings for each alternative
|
||||
alternateDescriptionFactory.AppendEncodedPolylineString(
|
||||
alternate_descriptionFactory.AppendEncodedPolylineString(
|
||||
config.encode_geometry,
|
||||
reply.content
|
||||
);
|
||||
}
|
||||
reply.content.push_back("],");
|
||||
reply.content.push_back("\"alternative_instructions\":[");
|
||||
entered_restricted_area_count = 0;
|
||||
if(INT_MAX != raw_route_information.lengthOfAlternativePath) {
|
||||
if(INT_MAX != raw_route.lengthOfAlternativePath) {
|
||||
reply.content.push_back("[");
|
||||
//Generate instructions for each alternative
|
||||
if(config.instructions) {
|
||||
BuildTextualDescription(
|
||||
alternateDescriptionFactory,
|
||||
alternate_descriptionFactory,
|
||||
reply,
|
||||
raw_route_information.lengthOfAlternativePath,
|
||||
raw_route.lengthOfAlternativePath,
|
||||
facade,
|
||||
alternative_path_segments
|
||||
);
|
||||
} else {
|
||||
BOOST_FOREACH(const SegmentInformation & segment, alternateDescriptionFactory.pathDescription) {
|
||||
TurnInstruction current_instruction = segment.turn_instruction & TurnInstructions.InverseAccessRestrictionFlag;
|
||||
entered_restricted_area_count += (current_instruction != segment.turn_instruction);
|
||||
}
|
||||
}
|
||||
reply.content.push_back("]");
|
||||
}
|
||||
reply.content.push_back("],");
|
||||
reply.content.push_back("\"alternative_summaries\":[");
|
||||
if(INT_MAX != raw_route_information.lengthOfAlternativePath) {
|
||||
if(INT_MAX != raw_route.lengthOfAlternativePath) {
|
||||
//Generate route summary (length, duration) for each alternative
|
||||
alternateDescriptionFactory.BuildRouteSummary(alternateDescriptionFactory.entireLength, raw_route_information.lengthOfAlternativePath - ( entered_restricted_area_count*TurnInstructions.AccessRestrictionPenalty));
|
||||
alternate_descriptionFactory.BuildRouteSummary(
|
||||
alternate_descriptionFactory.entireLength,
|
||||
raw_route.lengthOfAlternativePath
|
||||
);
|
||||
reply.content.push_back("{");
|
||||
reply.content.push_back("\"total_distance\":");
|
||||
reply.content.push_back(alternateDescriptionFactory.summary.lengthString);
|
||||
reply.content.push_back(
|
||||
alternate_descriptionFactory.summary.lengthString
|
||||
);
|
||||
reply.content.push_back(","
|
||||
"\"total_time\":");
|
||||
reply.content.push_back(alternateDescriptionFactory.summary.durationString);
|
||||
reply.content.push_back(
|
||||
alternate_descriptionFactory.summary.durationString
|
||||
);
|
||||
reply.content.push_back(","
|
||||
"\"start_point\":\"");
|
||||
reply.content.push_back(facade->GetEscapedNameForNameID(description_factory.summary.startName));
|
||||
reply.content.push_back(
|
||||
facade->GetEscapedNameForNameID(
|
||||
description_factory.summary.startName
|
||||
)
|
||||
);
|
||||
reply.content.push_back("\","
|
||||
"\"end_point\":\"");
|
||||
reply.content.push_back(facade->GetEscapedNameForNameID(description_factory.summary.destName));
|
||||
@@ -231,7 +259,7 @@ public:
|
||||
}
|
||||
reply.content.push_back("],");
|
||||
|
||||
//Get Names for both routes
|
||||
// //Get Names for both routes
|
||||
RouteNames routeNames;
|
||||
GetRouteNames(shortest_path_segments, alternative_path_segments, facade, routeNames);
|
||||
|
||||
@@ -249,47 +277,66 @@ public:
|
||||
reply.content.push_back("],");
|
||||
//list all viapoints so that the client may display it
|
||||
reply.content.push_back("\"via_points\":[");
|
||||
std::string tmp;
|
||||
if(config.geometry && INT_MAX != raw_route_information.lengthOfShortestPath) {
|
||||
for(unsigned i = 0; i < raw_route_information.segmentEndCoordinates.size(); ++i) {
|
||||
reply.content.push_back("[");
|
||||
if(raw_route_information.segmentEndCoordinates[i].startPhantom.location.isSet())
|
||||
convertInternalReversedCoordinateToString(raw_route_information.segmentEndCoordinates[i].startPhantom.location, tmp);
|
||||
else
|
||||
convertInternalReversedCoordinateToString(raw_route_information.rawViaNodeCoordinates[i], tmp);
|
||||
|
||||
reply.content.push_back(tmp);
|
||||
reply.content.push_back("],");
|
||||
}
|
||||
reply.content.push_back("[");
|
||||
if(raw_route_information.segmentEndCoordinates.back().startPhantom.location.isSet())
|
||||
convertInternalReversedCoordinateToString(raw_route_information.segmentEndCoordinates.back().targetPhantom.location, tmp);
|
||||
else
|
||||
convertInternalReversedCoordinateToString(raw_route_information.rawViaNodeCoordinates.back(), tmp);
|
||||
BOOST_ASSERT( !raw_route.segmentEndCoordinates.empty() );
|
||||
|
||||
std::string tmp;
|
||||
convertInternalReversedCoordinateToString(
|
||||
raw_route.segmentEndCoordinates.front().startPhantom.location,
|
||||
tmp
|
||||
);
|
||||
reply.content.push_back("[");
|
||||
reply.content.push_back(tmp);
|
||||
reply.content.push_back("]");
|
||||
|
||||
BOOST_FOREACH(const PhantomNodes & nodes, raw_route.segmentEndCoordinates) {
|
||||
tmp.clear();
|
||||
convertInternalReversedCoordinateToString(
|
||||
nodes.targetPhantom.location,
|
||||
tmp
|
||||
);
|
||||
reply.content.push_back(",[");
|
||||
reply.content.push_back(tmp);
|
||||
reply.content.push_back("]");
|
||||
}
|
||||
|
||||
reply.content.push_back("],");
|
||||
reply.content.push_back("\"via_indices\":[");
|
||||
BOOST_FOREACH(const unsigned index, shortest_leg_end_indices) {
|
||||
tmp.clear();
|
||||
intToString(index, tmp);
|
||||
reply.content.push_back(tmp);
|
||||
if( index != shortest_leg_end_indices.back() ) {
|
||||
reply.content.push_back(",");
|
||||
}
|
||||
}
|
||||
reply.content.push_back("],\"alternative_indices\":[");
|
||||
if(INT_MAX != raw_route.lengthOfAlternativePath) {
|
||||
reply.content.push_back("0,");
|
||||
tmp.clear();
|
||||
intToString(alternate_descriptionFactory.pathDescription.size(), tmp);
|
||||
reply.content.push_back(tmp);
|
||||
}
|
||||
|
||||
reply.content.push_back("],");
|
||||
reply.content.push_back("\"hint_data\": {");
|
||||
reply.content.push_back("\"checksum\":");
|
||||
intToString(raw_route_information.checkSum, tmp);
|
||||
intToString(raw_route.checkSum, tmp);
|
||||
reply.content.push_back(tmp);
|
||||
reply.content.push_back(", \"locations\": [");
|
||||
|
||||
std::string hint;
|
||||
for(unsigned i = 0; i < raw_route_information.segmentEndCoordinates.size(); ++i) {
|
||||
for(unsigned i = 0; i < raw_route.segmentEndCoordinates.size(); ++i) {
|
||||
reply.content.push_back("\"");
|
||||
EncodeObjectToBase64(raw_route_information.segmentEndCoordinates[i].startPhantom, hint);
|
||||
EncodeObjectToBase64(raw_route.segmentEndCoordinates[i].startPhantom, hint);
|
||||
reply.content.push_back(hint);
|
||||
reply.content.push_back("\", ");
|
||||
}
|
||||
EncodeObjectToBase64(raw_route_information.segmentEndCoordinates.back().targetPhantom, hint);
|
||||
EncodeObjectToBase64(raw_route.segmentEndCoordinates.back().targetPhantom, hint);
|
||||
reply.content.push_back("\"");
|
||||
reply.content.push_back(hint);
|
||||
reply.content.push_back("\"]");
|
||||
reply.content.push_back("},");
|
||||
reply.content.push_back("\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"");
|
||||
reply.content.push_back("}");
|
||||
reply.content.push_back("}}");
|
||||
}
|
||||
|
||||
// construct routes names
|
||||
@@ -357,14 +404,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
inline void WriteHeaderToOutput(std::vector<std::string> & output) {
|
||||
output.push_back(
|
||||
"{"
|
||||
"\"version\": 0.3,"
|
||||
"\"status\":"
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: reorder parameters
|
||||
inline void BuildTextualDescription(
|
||||
DescriptionFactory & description_factory,
|
||||
|
||||
Reference in New Issue
Block a user