(partially) migrate Descriptors to use C++11 syntax
This commit is contained in:
parent
946bfb9a26
commit
17ed4f908c
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BASE_DESCRIPTOR_H_
|
#ifndef BASE_DESCRIPTOR_H
|
||||||
#define BASE_DESCRIPTOR_H_
|
#define BASE_DESCRIPTOR_H
|
||||||
|
|
||||||
#include "../DataStructures/PhantomNodes.h"
|
#include "../DataStructures/PhantomNodes.h"
|
||||||
#include "../DataStructures/RawRouteData.h"
|
#include "../DataStructures/RawRouteData.h"
|
||||||
@ -37,32 +37,28 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct DescriptorConfig {
|
struct DescriptorConfig
|
||||||
DescriptorConfig() :
|
{
|
||||||
instructions(true),
|
DescriptorConfig() : instructions(true), geometry(true), encode_geometry(true), zoom_level(18)
|
||||||
geometry(true),
|
{
|
||||||
encode_geometry(true),
|
}
|
||||||
zoom_level(18)
|
|
||||||
{ }
|
|
||||||
bool instructions;
|
bool instructions;
|
||||||
bool geometry;
|
bool geometry;
|
||||||
bool encode_geometry;
|
bool encode_geometry;
|
||||||
unsigned short zoom_level;
|
unsigned short zoom_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class DataFacadeT>
|
template <class DataFacadeT> class BaseDescriptor
|
||||||
class BaseDescriptor {
|
{
|
||||||
public:
|
public:
|
||||||
BaseDescriptor() { }
|
BaseDescriptor() {}
|
||||||
//Maybe someone can explain the pure virtual destructor thing to me (dennis)
|
// Maybe someone can explain the pure virtual destructor thing to me (dennis)
|
||||||
virtual ~BaseDescriptor() { }
|
virtual ~BaseDescriptor() {}
|
||||||
virtual void Run(
|
virtual void Run(const RawRouteData &raw_route,
|
||||||
const RawRouteData & rawRoute,
|
const PhantomNodes &phantom_nodes,
|
||||||
const PhantomNodes & phantomNodes,
|
DataFacadeT *facade,
|
||||||
DataFacadeT * facade,
|
http::Reply &reply) = 0;
|
||||||
http::Reply & reply
|
virtual void SetConfig(const DescriptorConfig &config) = 0;
|
||||||
) = 0;
|
|
||||||
virtual void SetConfig(const DescriptorConfig & config) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BASE_DESCRIPTOR_H_ */
|
#endif // BASE_DESCRIPTOR_H
|
||||||
|
@ -27,26 +27,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include "DescriptionFactory.h"
|
#include "DescriptionFactory.h"
|
||||||
|
|
||||||
DescriptionFactory::DescriptionFactory() : entireLength(0) { }
|
DescriptionFactory::DescriptionFactory() : entireLength(0) {}
|
||||||
|
|
||||||
DescriptionFactory::~DescriptionFactory() { }
|
DescriptionFactory::~DescriptionFactory() {}
|
||||||
|
|
||||||
inline double DescriptionFactory::DegreeToRadian(const double degree) const
|
inline double DescriptionFactory::DegreeToRadian(const double degree) const
|
||||||
{
|
{
|
||||||
return degree * (M_PI/180.);
|
return degree * (M_PI / 180.);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double DescriptionFactory::RadianToDegree(const double radian) const
|
inline double DescriptionFactory::RadianToDegree(const double radian) const
|
||||||
{
|
{
|
||||||
return radian * (180./M_PI);
|
return radian * (180. / M_PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
double DescriptionFactory::GetBearing(const FixedPointCoordinate & A, const FixedPointCoordinate & B) const
|
double DescriptionFactory::GetBearing(const FixedPointCoordinate &A, const FixedPointCoordinate &B)
|
||||||
|
const
|
||||||
{
|
{
|
||||||
double delta_long = 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 lat1 = DegreeToRadian(A.lat / COORDINATE_PRECISION);
|
||||||
const double lat2 = DegreeToRadian(B.lat/COORDINATE_PRECISION);
|
const double lat2 = DegreeToRadian(B.lat / COORDINATE_PRECISION);
|
||||||
|
|
||||||
const double y = sin(delta_long) * cos(lat2);
|
const double y = sin(delta_long) * cos(lat2);
|
||||||
const double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_long);
|
const double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_long);
|
||||||
@ -63,77 +64,69 @@ double DescriptionFactory::GetBearing(const FixedPointCoordinate & A, const Fixe
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptionFactory::SetStartSegment(const PhantomNode & source, const bool source_traversed_in_reverse)
|
void DescriptionFactory::SetStartSegment(const PhantomNode &source,
|
||||||
|
const bool source_traversed_in_reverse)
|
||||||
{
|
{
|
||||||
start_phantom = source;
|
start_phantom = source;
|
||||||
AppendSegment(
|
AppendSegment(source.location, PathData(0, source.name_id, 10, source.forward_weight));
|
||||||
source.location,
|
|
||||||
PathData(0, source.name_id, 10, source.forward_weight)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptionFactory::SetEndSegment(const PhantomNode & target, const bool target_traversed_in_reverse)
|
void DescriptionFactory::SetEndSegment(const PhantomNode &target,
|
||||||
|
const bool target_traversed_in_reverse)
|
||||||
{
|
{
|
||||||
target_phantom = target;
|
target_phantom = target;
|
||||||
pathDescription.push_back(
|
path_description.push_back(
|
||||||
SegmentInformation(
|
SegmentInformation(target.location, target.name_id, 0, target.reverse_weight, 0, true));
|
||||||
target.location,
|
|
||||||
target.name_id,
|
|
||||||
0,
|
|
||||||
target.reverse_weight,
|
|
||||||
0,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptionFactory::AppendSegment(const FixedPointCoordinate & coordinate, const PathData & path_point)
|
void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
|
||||||
|
const PathData &path_point)
|
||||||
{
|
{
|
||||||
if ((1 == pathDescription.size()) && ( pathDescription.back().location == coordinate))
|
if ((1 == path_description.size()) && (path_description.back().location == coordinate))
|
||||||
{
|
{
|
||||||
pathDescription.back().name_id = path_point.name_id;
|
path_description.back().name_id = path_point.name_id;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pathDescription.push_back(
|
path_description.push_back(SegmentInformation(coordinate,
|
||||||
SegmentInformation(coordinate, path_point.name_id, path_point.durationOfSegment, 0, path_point.turnInstruction)
|
path_point.name_id,
|
||||||
);
|
path_point.durationOfSegment,
|
||||||
|
0,
|
||||||
|
path_point.turnInstruction));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptionFactory::AppendEncodedPolylineString(
|
void DescriptionFactory::AppendEncodedPolylineString(const bool return_encoded,
|
||||||
const bool return_encoded,
|
std::vector<std::string> &output)
|
||||||
std::vector<std::string> & output
|
{
|
||||||
) {
|
|
||||||
std::string temp;
|
std::string temp;
|
||||||
if(return_encoded) {
|
if (return_encoded)
|
||||||
polyline_compressor.printEncodedString(pathDescription, temp);
|
{
|
||||||
} else {
|
polyline_compressor.printEncodedString(path_description, temp);
|
||||||
polyline_compressor.printUnencodedString(pathDescription, temp);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
polyline_compressor.printUnencodedString(path_description, temp);
|
||||||
}
|
}
|
||||||
output.push_back(temp);
|
output.push_back(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptionFactory::AppendEncodedPolylineString(
|
void DescriptionFactory::AppendEncodedPolylineString(std::vector<std::string> &output) const
|
||||||
std::vector<std::string> &output
|
{
|
||||||
) const {
|
|
||||||
std::string temp;
|
std::string temp;
|
||||||
polyline_compressor.printEncodedString(pathDescription, temp);
|
polyline_compressor.printEncodedString(path_description, temp);
|
||||||
output.push_back(temp);
|
output.push_back(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptionFactory::AppendUnencodedPolylineString(
|
void DescriptionFactory::AppendUnencodedPolylineString(std::vector<std::string> &output) const
|
||||||
std::vector<std::string>& output
|
{
|
||||||
) const {
|
|
||||||
std::string temp;
|
std::string temp;
|
||||||
polyline_compressor.printUnencodedString(pathDescription, temp);
|
polyline_compressor.printUnencodedString(path_description, temp);
|
||||||
output.push_back(temp);
|
output.push_back(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptionFactory::BuildRouteSummary(
|
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time)
|
||||||
const double distance,
|
{
|
||||||
const unsigned time
|
|
||||||
) {
|
|
||||||
summary.startName = start_phantom.name_id;
|
summary.startName = start_phantom.name_id;
|
||||||
summary.destName = target_phantom.name_id;
|
summary.destName = target_phantom.name_id;
|
||||||
summary.BuildDurationAndLengthStrings(distance, time);
|
summary.BuildDurationAndLengthStrings(distance, time);
|
||||||
|
@ -45,71 +45,63 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
/* This class is fed with all way segments in consecutive order
|
/* This class is fed with all way segments in consecutive order
|
||||||
* and produces the description plus the encoded polyline */
|
* and produces the description plus the encoded polyline */
|
||||||
|
|
||||||
class DescriptionFactory {
|
class DescriptionFactory
|
||||||
|
{
|
||||||
DouglasPeucker polyline_generalizer;
|
DouglasPeucker polyline_generalizer;
|
||||||
PolylineCompressor polyline_compressor;
|
PolylineCompressor polyline_compressor;
|
||||||
PhantomNode start_phantom, target_phantom;
|
PhantomNode start_phantom, target_phantom;
|
||||||
|
|
||||||
double DegreeToRadian(const double degree) const;
|
double DegreeToRadian(const double degree) const;
|
||||||
double RadianToDegree(const double degree) const;
|
double RadianToDegree(const double degree) const;
|
||||||
public:
|
|
||||||
struct RouteSummary {
|
public:
|
||||||
|
struct RouteSummary
|
||||||
|
{
|
||||||
std::string lengthString;
|
std::string lengthString;
|
||||||
std::string durationString;
|
std::string durationString;
|
||||||
unsigned startName;
|
unsigned startName;
|
||||||
unsigned destName;
|
unsigned destName;
|
||||||
RouteSummary() :
|
RouteSummary() : lengthString("0"), durationString("0"), startName(0), destName(0) {}
|
||||||
lengthString("0"),
|
|
||||||
durationString("0"),
|
|
||||||
startName(0),
|
|
||||||
destName(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void BuildDurationAndLengthStrings(
|
void BuildDurationAndLengthStrings(const double distance, const unsigned time)
|
||||||
const double distance,
|
{
|
||||||
const unsigned time
|
// compute distance/duration for route summary
|
||||||
) {
|
|
||||||
//compute distance/duration for route summary
|
|
||||||
intToString(round(distance), lengthString);
|
intToString(round(distance), lengthString);
|
||||||
int travel_time = round(time/10.);
|
int travel_time = round(time / 10.);
|
||||||
intToString(std::max(travel_time, 1), durationString);
|
intToString(std::max(travel_time, 1), durationString);
|
||||||
}
|
}
|
||||||
} summary;
|
} summary;
|
||||||
|
|
||||||
double entireLength;
|
double entireLength;
|
||||||
|
|
||||||
//I know, declaring this public is considered bad. I'm lazy
|
// I know, declaring this public is considered bad. I'm lazy
|
||||||
std::vector <SegmentInformation> pathDescription;
|
std::vector<SegmentInformation> path_description;
|
||||||
DescriptionFactory();
|
DescriptionFactory();
|
||||||
virtual ~DescriptionFactory();
|
virtual ~DescriptionFactory();
|
||||||
double GetBearing(const FixedPointCoordinate& C, const FixedPointCoordinate& B) const;
|
double GetBearing(const FixedPointCoordinate &C, const FixedPointCoordinate &B) const;
|
||||||
void AppendEncodedPolylineString(std::vector<std::string> &output) const;
|
void AppendEncodedPolylineString(std::vector<std::string> &output) const;
|
||||||
void AppendUnencodedPolylineString(std::vector<std::string> &output) const;
|
void AppendUnencodedPolylineString(std::vector<std::string> &output) const;
|
||||||
void AppendSegment(const FixedPointCoordinate & coordinate, const PathData & data);
|
void AppendSegment(const FixedPointCoordinate &coordinate, const PathData &data);
|
||||||
void BuildRouteSummary(const double distance, const unsigned time);
|
void BuildRouteSummary(const double distance, const unsigned time);
|
||||||
void SetStartSegment(const PhantomNode & start_phantom, const bool source_traversed_in_reverse);
|
void SetStartSegment(const PhantomNode &start_phantom, const bool source_traversed_in_reverse);
|
||||||
void SetEndSegment(const PhantomNode & start_phantom, const bool target_traversed_in_reverse);
|
void SetEndSegment(const PhantomNode &start_phantom, const bool target_traversed_in_reverse);
|
||||||
void AppendEncodedPolylineString(
|
void AppendEncodedPolylineString(const bool return_encoded, std::vector<std::string> &output);
|
||||||
const bool return_encoded,
|
|
||||||
std::vector<std::string> & output
|
|
||||||
);
|
|
||||||
|
|
||||||
template<class DataFacadeT>
|
template <class DataFacadeT> void Run(const DataFacadeT *facade, const unsigned zoomLevel)
|
||||||
void Run(
|
{
|
||||||
const DataFacadeT * facade,
|
if (path_description.empty())
|
||||||
const unsigned zoomLevel
|
{
|
||||||
) {
|
|
||||||
if( pathDescription.empty() ) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** starts at index 1 */
|
/** starts at index 1 */
|
||||||
pathDescription[0].length = 0;
|
path_description[0].length = 0;
|
||||||
for (unsigned i = 1; i < pathDescription.size(); ++i)
|
for (unsigned i = 1; i < path_description.size(); ++i)
|
||||||
{
|
{
|
||||||
//move down names by one, q&d hack
|
// move down names by one, q&d hack
|
||||||
pathDescription[i-1].name_id = pathDescription[i].name_id;
|
path_description[i - 1].name_id = path_description[i].name_id;
|
||||||
pathDescription[i].length = FixedPointCoordinate::ApproximateEuclideanDistance(pathDescription[i-1].location, pathDescription[i].location);
|
path_description[i].length = FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||||
|
path_description[i - 1].location, path_description[i].location);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Simplify turn instructions
|
/*Simplify turn instructions
|
||||||
@ -121,84 +113,94 @@ public:
|
|||||||
becomes:
|
becomes:
|
||||||
10. Turn left on B 36 for 35 km
|
10. Turn left on B 36 for 35 km
|
||||||
*/
|
*/
|
||||||
//TODO: rework to check only end and start of string.
|
// TODO: rework to check only end and start of string.
|
||||||
// stl string is way to expensive
|
// stl string is way to expensive
|
||||||
|
|
||||||
// unsigned lastTurn = 0;
|
// unsigned lastTurn = 0;
|
||||||
// for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
// for(unsigned i = 1; i < path_description.size(); ++i) {
|
||||||
// string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].name_id);
|
// string1 = sEngine.GetEscapedNameForNameID(path_description[i].name_id);
|
||||||
// if(TurnInstructionsClass::GoStraight == pathDescription[i].turn_instruction) {
|
// if(TurnInstructionsClass::GoStraight == path_description[i].turn_instruction) {
|
||||||
// if(std::string::npos != string0.find(string1+";")
|
// 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+" ;")
|
// || 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;
|
// SimpleLogger().Write() << "->next correct: " << string0 << " contains " <<
|
||||||
// for(; lastTurn != i; ++lastTurn)
|
// string1;
|
||||||
// pathDescription[lastTurn].name_id = pathDescription[i].name_id;
|
// for(; lastTurn != i; ++lastTurn)
|
||||||
// pathDescription[i].turn_instruction = TurnInstructionsClass::NoTurn;
|
// path_description[lastTurn].name_id = path_description[i].name_id;
|
||||||
// } else if(std::string::npos != string1.find(string0+";")
|
// path_description[i].turn_instruction = TurnInstructionsClass::NoTurn;
|
||||||
// || std::string::npos != string1.find(";"+string0)
|
// } 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)
|
// || 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;
|
// SimpleLogger().Write() << "->prev correct: " << string1 << " contains " <<
|
||||||
// pathDescription[i].turn_instruction = TurnInstructionsClass::NoTurn;
|
// string0;
|
||||||
// }
|
// path_description[i].name_id = path_description[i-1].name_id;
|
||||||
// }
|
// path_description[i].turn_instruction = TurnInstructionsClass::NoTurn;
|
||||||
// if (TurnInstructionsClass::NoTurn != pathDescription[i].turn_instruction) {
|
// }
|
||||||
// lastTurn = i;
|
// }
|
||||||
// }
|
// if (TurnInstructionsClass::NoTurn != path_description[i].turn_instruction) {
|
||||||
// string0 = string1;
|
// lastTurn = i;
|
||||||
// }
|
// }
|
||||||
|
// string0 = string1;
|
||||||
|
// }
|
||||||
|
|
||||||
double segment_length = 0.;
|
double segment_length = 0.;
|
||||||
unsigned segment_duration = 0;
|
unsigned segment_duration = 0;
|
||||||
unsigned segment_start_index = 0;
|
unsigned segment_start_index = 0;
|
||||||
|
|
||||||
for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
for (unsigned i = 1; i < path_description.size(); ++i)
|
||||||
entireLength += pathDescription[i].length;
|
{
|
||||||
segment_length += pathDescription[i].length;
|
entireLength += path_description[i].length;
|
||||||
segment_duration += pathDescription[i].duration;
|
segment_length += path_description[i].length;
|
||||||
pathDescription[segment_start_index].length = segment_length;
|
segment_duration += path_description[i].duration;
|
||||||
pathDescription[segment_start_index].duration = segment_duration;
|
path_description[segment_start_index].length = segment_length;
|
||||||
|
path_description[segment_start_index].duration = segment_duration;
|
||||||
|
|
||||||
|
if (TurnInstructionsClass::NoTurn != path_description[i].turn_instruction)
|
||||||
if(TurnInstructionsClass::NoTurn != pathDescription[i].turn_instruction) {
|
{
|
||||||
BOOST_ASSERT(pathDescription[i].necessary);
|
BOOST_ASSERT(path_description[i].necessary);
|
||||||
segment_length = 0;
|
segment_length = 0;
|
||||||
segment_duration = 0;
|
segment_duration = 0;
|
||||||
segment_start_index = i;
|
segment_start_index = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Post-processing to remove empty or nearly empty path segments
|
// Post-processing to remove empty or nearly empty path segments
|
||||||
if(std::numeric_limits<double>::epsilon() > pathDescription.back().length) {
|
if (std::numeric_limits<double>::epsilon() > path_description.back().length)
|
||||||
if(pathDescription.size() > 2){
|
{
|
||||||
pathDescription.pop_back();
|
if (path_description.size() > 2)
|
||||||
pathDescription.back().necessary = true;
|
{
|
||||||
pathDescription.back().turn_instruction = TurnInstructionsClass::NoTurn;
|
path_description.pop_back();
|
||||||
target_phantom.name_id = (pathDescription.end()-2)->name_id;
|
path_description.back().necessary = true;
|
||||||
|
path_description.back().turn_instruction = TurnInstructionsClass::NoTurn;
|
||||||
|
target_phantom.name_id = (path_description.end() - 2)->name_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(std::numeric_limits<double>::epsilon() > pathDescription[0].length) {
|
if (std::numeric_limits<double>::epsilon() > path_description[0].length)
|
||||||
if(pathDescription.size() > 2) {
|
{
|
||||||
pathDescription.erase(pathDescription.begin());
|
if (path_description.size() > 2)
|
||||||
pathDescription[0].turn_instruction = TurnInstructionsClass::HeadOn;
|
{
|
||||||
pathDescription[0].necessary = true;
|
path_description.erase(path_description.begin());
|
||||||
start_phantom.name_id = pathDescription[0].name_id;
|
path_description[0].turn_instruction = TurnInstructionsClass::HeadOn;
|
||||||
|
path_description[0].necessary = true;
|
||||||
|
start_phantom.name_id = path_description[0].name_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Generalize poly line
|
// Generalize poly line
|
||||||
polyline_generalizer.Run(pathDescription, zoomLevel);
|
polyline_generalizer.Run(path_description, zoomLevel);
|
||||||
|
|
||||||
//fix what needs to be fixed else
|
// fix what needs to be fixed else
|
||||||
for(unsigned i = 0; i < pathDescription.size()-1 && pathDescription.size() >= 2; ++i){
|
for (unsigned i = 0; i < path_description.size() - 1 && path_description.size() >= 2; ++i)
|
||||||
if(pathDescription[i].necessary) {
|
{
|
||||||
double angle = GetBearing(pathDescription[i].location, pathDescription[i+1].location);
|
if (path_description[i].necessary)
|
||||||
pathDescription[i].bearing = angle*10;
|
{
|
||||||
|
double angle =
|
||||||
|
GetBearing(path_description[i].location, path_description[i + 1].location);
|
||||||
|
path_description[i].bearing = angle * 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -25,82 +25,72 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef GPX_DESCRIPTOR_H_
|
#ifndef GPX_DESCRIPTOR_H
|
||||||
#define GPX_DESCRIPTOR_H_
|
#define GPX_DESCRIPTOR_H
|
||||||
|
|
||||||
#include "BaseDescriptor.h"
|
#include "BaseDescriptor.h"
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFacadeT>
|
||||||
|
{
|
||||||
template<class DataFacadeT>
|
private:
|
||||||
class GPXDescriptor : public BaseDescriptor<DataFacadeT> {
|
|
||||||
private:
|
|
||||||
DescriptorConfig config;
|
DescriptorConfig config;
|
||||||
FixedPointCoordinate current;
|
FixedPointCoordinate current;
|
||||||
|
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
public:
|
|
||||||
void SetConfig(const DescriptorConfig & c) { config = c; }
|
|
||||||
|
|
||||||
//TODO: reorder parameters
|
public:
|
||||||
void Run(
|
void SetConfig(const DescriptorConfig &c) { config = c; }
|
||||||
const RawRouteData &raw_route,
|
|
||||||
const PhantomNodes &phantom_node_list,
|
// TODO: reorder parameters
|
||||||
DataFacadeT * facade,
|
void Run(const RawRouteData &raw_route,
|
||||||
http::Reply & reply
|
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("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||||
reply.content.push_back(
|
reply.content.push_back("<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" "
|
||||||
"<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" "
|
"xmlns=\"http://www.topografix.com/GPX/1/1\" "
|
||||||
"xmlns=\"http://www.topografix.com/GPX/1/1\" "
|
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
|
||||||
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
|
"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd"
|
||||||
"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd"
|
"\">");
|
||||||
"\">");
|
reply.content.push_back("<metadata><copyright author=\"Project OSRM\"><license>Data (c)"
|
||||||
reply.content.push_back(
|
" OpenStreetMap contributors (ODbL)</license></copyright>"
|
||||||
"<metadata><copyright author=\"Project OSRM\"><license>Data (c)"
|
"</metadata>");
|
||||||
" OpenStreetMap contributors (ODbL)</license></copyright>"
|
|
||||||
"</metadata>");
|
|
||||||
reply.content.push_back("<rte>");
|
reply.content.push_back("<rte>");
|
||||||
bool found_route = (raw_route.lengthOfShortestPath != INT_MAX) &&
|
bool found_route = (raw_route.lengthOfShortestPath != INVALID_EDGE_WEIGHT) &&
|
||||||
(raw_route.unpacked_path_segments[0].size());
|
(!raw_route.unpacked_path_segments.front().empty());
|
||||||
if( found_route ) {
|
if (found_route)
|
||||||
|
{
|
||||||
FixedPointCoordinate::convertInternalLatLonToString(
|
FixedPointCoordinate::convertInternalLatLonToString(
|
||||||
phantom_node_list.source_phantom.location.lat,
|
phantom_node_list.source_phantom.location.lat, tmp);
|
||||||
tmp
|
|
||||||
);
|
|
||||||
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
|
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
|
||||||
FixedPointCoordinate::convertInternalLatLonToString(
|
FixedPointCoordinate::convertInternalLatLonToString(
|
||||||
phantom_node_list.source_phantom.location.lon,
|
phantom_node_list.source_phantom.location.lon, tmp);
|
||||||
tmp
|
|
||||||
);
|
|
||||||
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
|
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
|
||||||
|
|
||||||
for(unsigned i=0; i < raw_route.unpacked_path_segments.size(); ++i){
|
for (const std::vector<PathData> &path_data_vector : raw_route.unpacked_path_segments)
|
||||||
BOOST_FOREACH(
|
{
|
||||||
const PathData & pathData,
|
for (const PathData &path_data : path_data_vector)
|
||||||
raw_route.unpacked_path_segments[i]
|
{
|
||||||
) {
|
FixedPointCoordinate current_coordinate = facade->GetCoordinateOfNode(path_data.node);
|
||||||
current = facade->GetCoordinateOfNode(pathData.node);
|
|
||||||
|
|
||||||
FixedPointCoordinate::convertInternalLatLonToString(current.lat, tmp);
|
FixedPointCoordinate::convertInternalLatLonToString(current_coordinate.lat,
|
||||||
|
tmp);
|
||||||
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
|
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
|
||||||
FixedPointCoordinate::convertInternalLatLonToString(current.lon, tmp);
|
FixedPointCoordinate::convertInternalLatLonToString(current_coordinate.lon,
|
||||||
|
tmp);
|
||||||
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
|
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add the via point or the end coordinate
|
// Add the via point or the end coordinate
|
||||||
FixedPointCoordinate::convertInternalLatLonToString(
|
FixedPointCoordinate::convertInternalLatLonToString(
|
||||||
phantom_node_list.target_phantom.location.lat,
|
phantom_node_list.target_phantom.location.lat, tmp);
|
||||||
tmp
|
|
||||||
);
|
|
||||||
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
|
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
|
||||||
FixedPointCoordinate::convertInternalLatLonToString(
|
FixedPointCoordinate::convertInternalLatLonToString(
|
||||||
phantom_node_list.target_phantom.location.lon,
|
phantom_node_list.target_phantom.location.lon, tmp);
|
||||||
tmp
|
|
||||||
);
|
|
||||||
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
|
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
|
||||||
}
|
}
|
||||||
reply.content.push_back("</rte></gpx>");
|
reply.content.push_back("</rte></gpx>");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif // GPX_DESCRIPTOR_H_
|
#endif // GPX_DESCRIPTOR_H
|
||||||
|
@ -36,33 +36,28 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "../Util/Azimuth.h"
|
#include "../Util/Azimuth.h"
|
||||||
#include "../Util/StringUtil.h"
|
#include "../Util/StringUtil.h"
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <boost/lambda/lambda.hpp>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
template<class DataFacadeT>
|
template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFacadeT>
|
||||||
class JSONDescriptor : public BaseDescriptor<DataFacadeT> {
|
{
|
||||||
private:
|
private:
|
||||||
// TODO: initalize in c'tor
|
// TODO: initalize in c'tor
|
||||||
DataFacadeT * facade;
|
DataFacadeT *facade;
|
||||||
DescriptorConfig config;
|
DescriptorConfig config;
|
||||||
DescriptionFactory description_factory;
|
DescriptionFactory description_factory;
|
||||||
DescriptionFactory alternate_descriptionFactory;
|
DescriptionFactory alternate_descriptionFactory;
|
||||||
FixedPointCoordinate current;
|
FixedPointCoordinate current;
|
||||||
unsigned entered_restricted_area_count;
|
unsigned entered_restricted_area_count;
|
||||||
struct RoundAbout{
|
struct RoundAbout
|
||||||
RoundAbout() :
|
{
|
||||||
start_index(INT_MAX),
|
RoundAbout() : start_index(INT_MAX), name_id(INT_MAX), leave_at_exit(INT_MAX) {}
|
||||||
name_id(INT_MAX),
|
|
||||||
leave_at_exit(INT_MAX)
|
|
||||||
{}
|
|
||||||
int start_index;
|
int start_index;
|
||||||
int name_id;
|
int name_id;
|
||||||
int leave_at_exit;
|
int leave_at_exit;
|
||||||
} round_about;
|
} round_about;
|
||||||
|
|
||||||
struct Segment {
|
struct Segment
|
||||||
|
{
|
||||||
Segment() : name_id(-1), length(-1), position(-1) {}
|
Segment() : name_id(-1), length(-1), position(-1) {}
|
||||||
Segment(int n, int l, int p) : name_id(n), length(l), position(p) {}
|
Segment(int n, int l, int p) : name_id(n), length(l), position(p) {}
|
||||||
int name_id;
|
int name_id;
|
||||||
@ -72,219 +67,186 @@ private:
|
|||||||
std::vector<Segment> shortest_path_segments, alternative_path_segments;
|
std::vector<Segment> shortest_path_segments, alternative_path_segments;
|
||||||
std::vector<unsigned> shortest_leg_end_indices, alternative_leg_end_indices;
|
std::vector<unsigned> shortest_leg_end_indices, alternative_leg_end_indices;
|
||||||
|
|
||||||
struct RouteNames {
|
struct RouteNames
|
||||||
std::string shortestPathName1;
|
{
|
||||||
std::string shortestPathName2;
|
std::string shortest_path_name_1;
|
||||||
std::string alternativePathName1;
|
std::string shortest_path_name_2;
|
||||||
std::string alternativePathName2;
|
std::string alternative_path_name_1;
|
||||||
|
std::string alternative_path_name_2;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JSONDescriptor() :
|
JSONDescriptor() : facade(nullptr), entered_restricted_area_count(0)
|
||||||
facade(NULL),
|
|
||||||
entered_restricted_area_count(0)
|
|
||||||
{
|
{
|
||||||
shortest_leg_end_indices.push_back(0);
|
shortest_leg_end_indices.push_back(0);
|
||||||
alternative_leg_end_indices.push_back(0);
|
alternative_leg_end_indices.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetConfig(const DescriptorConfig & c) { config = c; }
|
void SetConfig(const DescriptorConfig &c) { config = c; }
|
||||||
|
|
||||||
int DescribeLeg(
|
unsigned DescribeLeg(const std::vector<PathData> route_leg, const PhantomNodes &leg_phantoms)
|
||||||
const std::vector<PathData> route_leg,
|
{
|
||||||
const PhantomNodes & leg_phantoms
|
unsigned added_element_count = 0;
|
||||||
) {
|
// Get all the coordinates for the computed route
|
||||||
int added_element_count = 0;
|
|
||||||
//Get all the coordinates for the computed route
|
|
||||||
FixedPointCoordinate current_coordinate;
|
FixedPointCoordinate current_coordinate;
|
||||||
BOOST_FOREACH(const PathData & path_data, route_leg) {
|
for (const PathData &path_data : route_leg)
|
||||||
|
{
|
||||||
current_coordinate = facade->GetCoordinateOfNode(path_data.node);
|
current_coordinate = facade->GetCoordinateOfNode(path_data.node);
|
||||||
description_factory.AppendSegment(current_coordinate, path_data);
|
description_factory.AppendSegment(current_coordinate, path_data);
|
||||||
++added_element_count;
|
++added_element_count;
|
||||||
}
|
}
|
||||||
// description_factory.SetEndSegment( leg_phantoms.target_phantom );
|
// description_factory.SetEndSegment( leg_phantoms.target_phantom );
|
||||||
++added_element_count;
|
++added_element_count;
|
||||||
BOOST_ASSERT( (int)(route_leg.size() + 1) == added_element_count );
|
BOOST_ASSERT((route_leg.size() + 1) == added_element_count);
|
||||||
return added_element_count;
|
return added_element_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Run(
|
void Run(const RawRouteData &raw_route,
|
||||||
const RawRouteData & raw_route,
|
const PhantomNodes &phantom_nodes,
|
||||||
const PhantomNodes & phantom_nodes,
|
// TODO: move facade initalization to c'tor
|
||||||
// TODO: move facade initalization to c'tor
|
DataFacadeT *f,
|
||||||
DataFacadeT * f,
|
http::Reply &reply)
|
||||||
http::Reply & reply
|
{
|
||||||
) {
|
|
||||||
facade = f;
|
facade = f;
|
||||||
reply.content.push_back(
|
reply.content.push_back("{\"status\":");
|
||||||
"{\"status\":"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (INVALID_EDGE_WEIGHT == raw_route.lengthOfShortestPath)
|
if (INVALID_EDGE_WEIGHT == raw_route.lengthOfShortestPath)
|
||||||
{
|
{
|
||||||
//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.push_back(
|
reply.content.push_back(
|
||||||
"207,\"status_message\": \"Cannot find route between points\"}"
|
"207,\"status_message\": \"Cannot find route between points\"}");
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.lengthOfShortestPath;
|
SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.lengthOfShortestPath;
|
||||||
|
|
||||||
//check if first segment is non-zero
|
// check if first segment is non-zero
|
||||||
std::string road_name;
|
std::string road_name =
|
||||||
road_name = facade->GetEscapedNameForNameID(phantom_nodes.source_phantom.name_id);
|
facade->GetEscapedNameForNameID(phantom_nodes.source_phantom.name_id);
|
||||||
|
|
||||||
|
BOOST_ASSERT(raw_route.unpacked_path_segments.size() ==
|
||||||
|
raw_route.segmentEndCoordinates.size());
|
||||||
|
|
||||||
|
description_factory.SetStartSegment(phantom_nodes.source_phantom,
|
||||||
|
raw_route.source_traversed_in_reverse);
|
||||||
|
reply.content.push_back("0,"
|
||||||
|
"\"status_message\": \"Found route between points\",");
|
||||||
|
|
||||||
// for each unpacked segment add the leg to the description
|
// for each unpacked segment add the leg to the description
|
||||||
BOOST_ASSERT( raw_route.unpacked_path_segments.size() == raw_route.segmentEndCoordinates.size() );
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
|
for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
|
||||||
{
|
{
|
||||||
const std::vector<PathData> & leg_path = raw_route.unpacked_path_segments[i];
|
const int added_segments = DescribeLeg(raw_route.unpacked_path_segments[i],
|
||||||
FixedPointCoordinate current_coordinate;
|
raw_route.segmentEndCoordinates[i]);
|
||||||
BOOST_FOREACH(const PathData & path_data, leg_path)
|
BOOST_ASSERT(0 < added_segments);
|
||||||
{
|
shortest_leg_end_indices.push_back(added_segments + shortest_leg_end_indices.back());
|
||||||
current_coordinate = facade->GetCoordinateOfNode(path_data.node);
|
|
||||||
road_name = facade->GetEscapedNameForNameID(path_data.name_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
description_factory.SetEndSegment(phantom_nodes.target_phantom,
|
||||||
//check if last segment is non-zero
|
raw_route.target_traversed_in_reverse);
|
||||||
road_name = facade->GetEscapedNameForNameID(phantom_nodes.target_phantom.name_id);
|
|
||||||
|
|
||||||
description_factory.SetStartSegment(phantom_nodes.source_phantom, raw_route.source_traversed_in_reverse);
|
|
||||||
reply.content.push_back("0,"
|
|
||||||
"\"status_message\": \"Found route between points\",");
|
|
||||||
|
|
||||||
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.target_phantom, raw_route.target_traversed_in_reverse);
|
|
||||||
description_factory.Run(facade, config.zoom_level);
|
description_factory.Run(facade, config.zoom_level);
|
||||||
|
|
||||||
reply.content.push_back("\"route_geometry\": ");
|
reply.content.push_back("\"route_geometry\": ");
|
||||||
if(config.geometry) {
|
if (config.geometry)
|
||||||
description_factory.AppendEncodedPolylineString(
|
{
|
||||||
config.encode_geometry,
|
description_factory.AppendEncodedPolylineString(config.encode_geometry, reply.content);
|
||||||
reply.content
|
}
|
||||||
);
|
else
|
||||||
} else {
|
{
|
||||||
reply.content.push_back("[]");
|
reply.content.push_back("[]");
|
||||||
}
|
}
|
||||||
|
|
||||||
reply.content.push_back(",\"route_instructions\": [");
|
reply.content.push_back(",\"route_instructions\": [");
|
||||||
if(config.instructions) {
|
if (config.instructions)
|
||||||
BuildTextualDescription(
|
{
|
||||||
description_factory,
|
BuildTextualDescription(description_factory,
|
||||||
reply,
|
reply,
|
||||||
raw_route.lengthOfShortestPath,
|
raw_route.lengthOfShortestPath,
|
||||||
facade,
|
facade,
|
||||||
shortest_path_segments
|
shortest_path_segments);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
reply.content.push_back("],");
|
reply.content.push_back("],");
|
||||||
description_factory.BuildRouteSummary(
|
description_factory.BuildRouteSummary(description_factory.entireLength,
|
||||||
description_factory.entireLength,
|
raw_route.lengthOfShortestPath);
|
||||||
raw_route.lengthOfShortestPath
|
|
||||||
);
|
|
||||||
|
|
||||||
reply.content.push_back("\"route_summary\":");
|
reply.content.push_back("\"route_summary\":");
|
||||||
reply.content.push_back("{");
|
reply.content.push_back("{");
|
||||||
reply.content.push_back("\"total_distance\":");
|
reply.content.push_back("\"total_distance\":");
|
||||||
reply.content.push_back(description_factory.summary.lengthString);
|
reply.content.push_back(description_factory.summary.lengthString);
|
||||||
reply.content.push_back(","
|
reply.content.push_back(","
|
||||||
"\"total_time\":");
|
"\"total_time\":");
|
||||||
reply.content.push_back(description_factory.summary.durationString);
|
reply.content.push_back(description_factory.summary.durationString);
|
||||||
reply.content.push_back(","
|
reply.content.push_back(","
|
||||||
"\"start_point\":\"");
|
"\"start_point\":\"");
|
||||||
reply.content.push_back(
|
reply.content.push_back(
|
||||||
facade->GetEscapedNameForNameID(description_factory.summary.startName)
|
facade->GetEscapedNameForNameID(description_factory.summary.startName));
|
||||||
);
|
|
||||||
reply.content.push_back("\","
|
reply.content.push_back("\","
|
||||||
"\"end_point\":\"");
|
"\"end_point\":\"");
|
||||||
reply.content.push_back(
|
reply.content.push_back(
|
||||||
facade->GetEscapedNameForNameID(description_factory.summary.destName)
|
facade->GetEscapedNameForNameID(description_factory.summary.destName));
|
||||||
);
|
|
||||||
reply.content.push_back("\"");
|
reply.content.push_back("\"");
|
||||||
reply.content.push_back("}");
|
reply.content.push_back("}");
|
||||||
reply.content.push_back(",");
|
reply.content.push_back(",");
|
||||||
|
|
||||||
//only one alternative route is computed at this time, so this is hardcoded
|
// only one alternative route is computed at this time, so this is hardcoded
|
||||||
|
if (raw_route.lengthOfAlternativePath != INVALID_EDGE_WEIGHT)
|
||||||
if(raw_route.lengthOfAlternativePath != INVALID_EDGE_WEIGHT)
|
|
||||||
{
|
{
|
||||||
alternate_descriptionFactory.SetStartSegment(phantom_nodes.source_phantom, raw_route.alt_source_traversed_in_reverse);
|
alternate_descriptionFactory.SetStartSegment(phantom_nodes.source_phantom,
|
||||||
//Get all the coordinates for the computed route
|
raw_route.alt_source_traversed_in_reverse);
|
||||||
BOOST_FOREACH(const PathData & path_data, raw_route.unpacked_alternative) {
|
// Get all the coordinates for the computed route
|
||||||
|
for (const PathData &path_data : raw_route.unpacked_alternative)
|
||||||
|
{
|
||||||
current = facade->GetCoordinateOfNode(path_data.node);
|
current = facade->GetCoordinateOfNode(path_data.node);
|
||||||
alternate_descriptionFactory.AppendSegment(current, path_data );
|
alternate_descriptionFactory.AppendSegment(current, path_data);
|
||||||
}
|
}
|
||||||
alternate_descriptionFactory.SetEndSegment(phantom_nodes.target_phantom, raw_route.alt_target_traversed_in_reverse);
|
alternate_descriptionFactory.SetEndSegment(phantom_nodes.target_phantom,
|
||||||
|
raw_route.alt_target_traversed_in_reverse);
|
||||||
}
|
}
|
||||||
alternate_descriptionFactory.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\": [");
|
reply.content.push_back("\"alternative_geometries\": [");
|
||||||
if(config.geometry && INT_MAX != raw_route.lengthOfAlternativePath) {
|
if (config.geometry && INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath)
|
||||||
//Generate the linestrings for each alternative
|
{
|
||||||
alternate_descriptionFactory.AppendEncodedPolylineString(
|
// Generate the linestrings for each alternative
|
||||||
config.encode_geometry,
|
alternate_descriptionFactory.AppendEncodedPolylineString(config.encode_geometry,
|
||||||
reply.content
|
reply.content);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
reply.content.push_back("],");
|
reply.content.push_back("],");
|
||||||
reply.content.push_back("\"alternative_instructions\":[");
|
reply.content.push_back("\"alternative_instructions\":[");
|
||||||
if(INT_MAX != raw_route.lengthOfAlternativePath) {
|
if (INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath)
|
||||||
|
{
|
||||||
reply.content.push_back("[");
|
reply.content.push_back("[");
|
||||||
//Generate instructions for each alternative
|
// Generate instructions for each alternative
|
||||||
if(config.instructions) {
|
if (config.instructions)
|
||||||
BuildTextualDescription(
|
{
|
||||||
alternate_descriptionFactory,
|
BuildTextualDescription(alternate_descriptionFactory,
|
||||||
reply,
|
reply,
|
||||||
raw_route.lengthOfAlternativePath,
|
raw_route.lengthOfAlternativePath,
|
||||||
facade,
|
facade,
|
||||||
alternative_path_segments
|
alternative_path_segments);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
reply.content.push_back("]");
|
reply.content.push_back("]");
|
||||||
}
|
}
|
||||||
reply.content.push_back("],");
|
reply.content.push_back("],");
|
||||||
reply.content.push_back("\"alternative_summaries\":[");
|
reply.content.push_back("\"alternative_summaries\":[");
|
||||||
if(INT_MAX != raw_route.lengthOfAlternativePath) {
|
if (INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath)
|
||||||
//Generate route summary (length, duration) for each alternative
|
{
|
||||||
|
// Generate route summary (length, duration) for each alternative
|
||||||
alternate_descriptionFactory.BuildRouteSummary(
|
alternate_descriptionFactory.BuildRouteSummary(
|
||||||
alternate_descriptionFactory.entireLength,
|
alternate_descriptionFactory.entireLength, raw_route.lengthOfAlternativePath);
|
||||||
raw_route.lengthOfAlternativePath
|
|
||||||
);
|
|
||||||
reply.content.push_back("{");
|
reply.content.push_back("{");
|
||||||
reply.content.push_back("\"total_distance\":");
|
reply.content.push_back("\"total_distance\":");
|
||||||
reply.content.push_back(
|
reply.content.push_back(alternate_descriptionFactory.summary.lengthString);
|
||||||
alternate_descriptionFactory.summary.lengthString
|
|
||||||
);
|
|
||||||
reply.content.push_back(","
|
reply.content.push_back(","
|
||||||
"\"total_time\":");
|
"\"total_time\":");
|
||||||
reply.content.push_back(
|
reply.content.push_back(alternate_descriptionFactory.summary.durationString);
|
||||||
alternate_descriptionFactory.summary.durationString
|
|
||||||
);
|
|
||||||
reply.content.push_back(","
|
reply.content.push_back(","
|
||||||
"\"start_point\":\"");
|
"\"start_point\":\"");
|
||||||
reply.content.push_back(
|
reply.content.push_back(
|
||||||
facade->GetEscapedNameForNameID(
|
facade->GetEscapedNameForNameID(description_factory.summary.startName));
|
||||||
description_factory.summary.startName
|
|
||||||
)
|
|
||||||
);
|
|
||||||
reply.content.push_back("\","
|
reply.content.push_back("\","
|
||||||
"\"end_point\":\"");
|
"\"end_point\":\"");
|
||||||
reply.content.push_back(facade->GetEscapedNameForNameID(description_factory.summary.destName));
|
reply.content.push_back(
|
||||||
|
facade->GetEscapedNameForNameID(description_factory.summary.destName));
|
||||||
reply.content.push_back("\"");
|
reply.content.push_back("\"");
|
||||||
reply.content.push_back("}");
|
reply.content.push_back("}");
|
||||||
}
|
}
|
||||||
@ -295,37 +257,34 @@ public:
|
|||||||
GetRouteNames(shortest_path_segments, alternative_path_segments, facade, routeNames);
|
GetRouteNames(shortest_path_segments, alternative_path_segments, facade, routeNames);
|
||||||
|
|
||||||
reply.content.push_back("\"route_name\":[\"");
|
reply.content.push_back("\"route_name\":[\"");
|
||||||
reply.content.push_back(routeNames.shortestPathName1);
|
reply.content.push_back(routeNames.shortest_path_name_1);
|
||||||
reply.content.push_back("\",\"");
|
reply.content.push_back("\",\"");
|
||||||
reply.content.push_back(routeNames.shortestPathName2);
|
reply.content.push_back(routeNames.shortest_path_name_2);
|
||||||
reply.content.push_back("\"],"
|
reply.content.push_back("\"],"
|
||||||
"\"alternative_names\":[");
|
"\"alternative_names\":[");
|
||||||
reply.content.push_back("[\"");
|
reply.content.push_back("[\"");
|
||||||
reply.content.push_back(routeNames.alternativePathName1);
|
reply.content.push_back(routeNames.alternative_path_name_1);
|
||||||
reply.content.push_back("\",\"");
|
reply.content.push_back("\",\"");
|
||||||
reply.content.push_back(routeNames.alternativePathName2);
|
reply.content.push_back(routeNames.alternative_path_name_2);
|
||||||
reply.content.push_back("\"]");
|
reply.content.push_back("\"]");
|
||||||
reply.content.push_back("],");
|
reply.content.push_back("],");
|
||||||
//list all viapoints so that the client may display it
|
// list all viapoints so that the client may display it
|
||||||
reply.content.push_back("\"via_points\":[");
|
reply.content.push_back("\"via_points\":[");
|
||||||
|
|
||||||
BOOST_ASSERT( !raw_route.segmentEndCoordinates.empty() );
|
BOOST_ASSERT(!raw_route.segmentEndCoordinates.empty());
|
||||||
|
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
FixedPointCoordinate::convertInternalReversedCoordinateToString(
|
FixedPointCoordinate::convertInternalReversedCoordinateToString(
|
||||||
raw_route.segmentEndCoordinates.front().source_phantom.location,
|
raw_route.segmentEndCoordinates.front().source_phantom.location, tmp);
|
||||||
tmp
|
|
||||||
);
|
|
||||||
reply.content.push_back("[");
|
reply.content.push_back("[");
|
||||||
reply.content.push_back(tmp);
|
reply.content.push_back(tmp);
|
||||||
reply.content.push_back("]");
|
reply.content.push_back("]");
|
||||||
|
|
||||||
BOOST_FOREACH(const PhantomNodes & nodes, raw_route.segmentEndCoordinates) {
|
for (const PhantomNodes &nodes : raw_route.segmentEndCoordinates)
|
||||||
|
{
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
FixedPointCoordinate::convertInternalReversedCoordinateToString(
|
FixedPointCoordinate::convertInternalReversedCoordinateToString(
|
||||||
nodes.target_phantom.location,
|
nodes.target_phantom.location, tmp);
|
||||||
tmp
|
|
||||||
);
|
|
||||||
reply.content.push_back(",[");
|
reply.content.push_back(",[");
|
||||||
reply.content.push_back(tmp);
|
reply.content.push_back(tmp);
|
||||||
reply.content.push_back("]");
|
reply.content.push_back("]");
|
||||||
@ -333,19 +292,22 @@ public:
|
|||||||
|
|
||||||
reply.content.push_back("],");
|
reply.content.push_back("],");
|
||||||
reply.content.push_back("\"via_indices\":[");
|
reply.content.push_back("\"via_indices\":[");
|
||||||
BOOST_FOREACH(const unsigned index, shortest_leg_end_indices) {
|
for (const unsigned index : shortest_leg_end_indices)
|
||||||
|
{
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
intToString(index, tmp);
|
intToString(index, tmp);
|
||||||
reply.content.push_back(tmp);
|
reply.content.push_back(tmp);
|
||||||
if( index != shortest_leg_end_indices.back() ) {
|
if (index != shortest_leg_end_indices.back())
|
||||||
|
{
|
||||||
reply.content.push_back(",");
|
reply.content.push_back(",");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reply.content.push_back("],\"alternative_indices\":[");
|
reply.content.push_back("],\"alternative_indices\":[");
|
||||||
if(INT_MAX != raw_route.lengthOfAlternativePath) {
|
if (INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath)
|
||||||
|
{
|
||||||
reply.content.push_back("0,");
|
reply.content.push_back("0,");
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
intToString(alternate_descriptionFactory.pathDescription.size(), tmp);
|
intToString(alternate_descriptionFactory.path_description.size(), tmp);
|
||||||
reply.content.push_back(tmp);
|
reply.content.push_back(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +319,8 @@ public:
|
|||||||
reply.content.push_back(", \"locations\": [");
|
reply.content.push_back(", \"locations\": [");
|
||||||
|
|
||||||
std::string hint;
|
std::string hint;
|
||||||
for(unsigned i = 0; i < raw_route.segmentEndCoordinates.size(); ++i) {
|
for (unsigned i = 0; i < raw_route.segmentEndCoordinates.size(); ++i)
|
||||||
|
{
|
||||||
reply.content.push_back("\"");
|
reply.content.push_back("\"");
|
||||||
EncodeObjectToBase64(raw_route.segmentEndCoordinates[i].source_phantom, hint);
|
EncodeObjectToBase64(raw_route.segmentEndCoordinates[i].source_phantom, hint);
|
||||||
reply.content.push_back(hint);
|
reply.content.push_back(hint);
|
||||||
@ -371,91 +334,115 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// construct routes names
|
// construct routes names
|
||||||
void GetRouteNames(
|
void GetRouteNames(std::vector<Segment> &shortest_path_segments,
|
||||||
std::vector<Segment> & shortest_path_segments,
|
std::vector<Segment> &alternative_path_segments,
|
||||||
std::vector<Segment> & alternative_path_segments,
|
const DataFacadeT *facade,
|
||||||
const DataFacadeT * facade,
|
RouteNames &routeNames)
|
||||||
RouteNames & routeNames
|
{
|
||||||
) {
|
Segment shortest_segment_1, shortest_segment_2;
|
||||||
|
Segment alternativeSegment1, alternative_segment_2;
|
||||||
|
|
||||||
Segment shortestSegment1, shortestSegment2;
|
auto length_comperator = [](Segment a, Segment b)
|
||||||
Segment alternativeSegment1, alternativeSegment2;
|
{ return a.length < b.length; };
|
||||||
|
auto name_id_comperator = [](Segment a, Segment b)
|
||||||
|
{ return a.name_id < b.name_id; };
|
||||||
|
|
||||||
if(0 < shortest_path_segments.size()) {
|
if (!shortest_path_segments.empty())
|
||||||
sort(shortest_path_segments.begin(), shortest_path_segments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
|
{
|
||||||
shortestSegment1 = shortest_path_segments[0];
|
std::sort(shortest_path_segments.begin(),
|
||||||
if(0 < alternative_path_segments.size()) {
|
shortest_path_segments.end(),
|
||||||
sort(alternative_path_segments.begin(), alternative_path_segments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
|
length_comperator);
|
||||||
|
shortest_segment_1 = shortest_path_segments[0];
|
||||||
|
if (!alternative_path_segments.empty())
|
||||||
|
{
|
||||||
|
std::sort(alternative_path_segments.begin(),
|
||||||
|
alternative_path_segments.end(),
|
||||||
|
length_comperator);
|
||||||
alternativeSegment1 = alternative_path_segments[0];
|
alternativeSegment1 = alternative_path_segments[0];
|
||||||
}
|
}
|
||||||
std::vector<Segment> shortestDifference(shortest_path_segments.size());
|
std::vector<Segment> shortestDifference(shortest_path_segments.size());
|
||||||
std::vector<Segment> alternativeDifference(alternative_path_segments.size());
|
std::vector<Segment> alternativeDifference(alternative_path_segments.size());
|
||||||
std::set_difference(shortest_path_segments.begin(), shortest_path_segments.end(), alternative_path_segments.begin(), alternative_path_segments.end(), shortestDifference.begin(), boost::bind(&Segment::name_id, _1) < boost::bind(&Segment::name_id, _2) );
|
std::set_difference(shortest_path_segments.begin(),
|
||||||
|
shortest_path_segments.end(),
|
||||||
|
alternative_path_segments.begin(),
|
||||||
|
alternative_path_segments.end(),
|
||||||
|
shortestDifference.begin(),
|
||||||
|
length_comperator);
|
||||||
int size_of_difference = shortestDifference.size();
|
int size_of_difference = shortestDifference.size();
|
||||||
if(0 < size_of_difference ) {
|
if (size_of_difference)
|
||||||
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while( i < size_of_difference && shortestDifference[i].name_id == shortest_path_segments[0].name_id) {
|
while (i < size_of_difference &&
|
||||||
|
shortestDifference[i].name_id == shortest_path_segments[0].name_id)
|
||||||
|
{
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
if(i < size_of_difference ) {
|
if (i < size_of_difference)
|
||||||
shortestSegment2 = shortestDifference[i];
|
{
|
||||||
|
shortest_segment_2 = shortestDifference[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set_difference(alternative_path_segments.begin(), alternative_path_segments.end(), shortest_path_segments.begin(), shortest_path_segments.end(), alternativeDifference.begin(), boost::bind(&Segment::name_id, _1) < boost::bind(&Segment::name_id, _2) );
|
std::set_difference(alternative_path_segments.begin(),
|
||||||
|
alternative_path_segments.end(),
|
||||||
|
shortest_path_segments.begin(),
|
||||||
|
shortest_path_segments.end(),
|
||||||
|
alternativeDifference.begin(),
|
||||||
|
name_id_comperator);
|
||||||
size_of_difference = alternativeDifference.size();
|
size_of_difference = alternativeDifference.size();
|
||||||
if(0 < size_of_difference ) {
|
if (size_of_difference)
|
||||||
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while( i < size_of_difference && alternativeDifference[i].name_id == alternative_path_segments[0].name_id) {
|
while (i < size_of_difference &&
|
||||||
|
alternativeDifference[i].name_id == alternative_path_segments[0].name_id)
|
||||||
|
{
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
if(i < size_of_difference ) {
|
if (i < size_of_difference)
|
||||||
alternativeSegment2 = alternativeDifference[i];
|
{
|
||||||
|
alternative_segment_2 = alternativeDifference[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(shortestSegment1.position > shortestSegment2.position)
|
if (shortest_segment_1.position > shortest_segment_2.position)
|
||||||
std::swap(shortestSegment1, shortestSegment2);
|
std::swap(shortest_segment_1, shortest_segment_2);
|
||||||
|
|
||||||
if(alternativeSegment1.position > alternativeSegment2.position)
|
if (alternativeSegment1.position > alternative_segment_2.position)
|
||||||
std::swap(alternativeSegment1, alternativeSegment2);
|
std::swap(alternativeSegment1, alternative_segment_2);
|
||||||
|
|
||||||
routeNames.shortestPathName1 = facade->GetEscapedNameForNameID(
|
routeNames.shortest_path_name_1 =
|
||||||
shortestSegment1.name_id
|
facade->GetEscapedNameForNameID(shortest_segment_1.name_id);
|
||||||
);
|
routeNames.shortest_path_name_2 =
|
||||||
routeNames.shortestPathName2 = facade->GetEscapedNameForNameID(
|
facade->GetEscapedNameForNameID(shortest_segment_2.name_id);
|
||||||
shortestSegment2.name_id
|
|
||||||
);
|
|
||||||
|
|
||||||
routeNames.alternativePathName1 = facade->GetEscapedNameForNameID(
|
routeNames.alternative_path_name_1 =
|
||||||
alternativeSegment1.name_id
|
facade->GetEscapedNameForNameID(alternativeSegment1.name_id);
|
||||||
);
|
routeNames.alternative_path_name_2 =
|
||||||
routeNames.alternativePathName2 = facade->GetEscapedNameForNameID(
|
facade->GetEscapedNameForNameID(alternative_segment_2.name_id);
|
||||||
alternativeSegment2.name_id
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: reorder parameters
|
// TODO: reorder parameters
|
||||||
inline void BuildTextualDescription(
|
inline void BuildTextualDescription(DescriptionFactory &description_factory,
|
||||||
DescriptionFactory & description_factory,
|
http::Reply &reply,
|
||||||
http::Reply & reply,
|
const int route_length,
|
||||||
const int route_length,
|
const DataFacadeT *facade,
|
||||||
const DataFacadeT * facade,
|
std::vector<Segment> &route_segments_list)
|
||||||
std::vector<Segment> & route_segments_list
|
{
|
||||||
) {
|
// 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]
|
||||||
unsigned necessary_segments_running_index = 0;
|
unsigned necessary_segments_running_index = 0;
|
||||||
round_about.leave_at_exit = 0;
|
round_about.leave_at_exit = 0;
|
||||||
round_about.name_id = 0;
|
round_about.name_id = 0;
|
||||||
std::string temp_dist, temp_length, temp_duration, temp_bearing, temp_instruction;
|
std::string temp_dist, temp_length, temp_duration, temp_bearing, temp_instruction;
|
||||||
|
|
||||||
//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, description_factory.pathDescription) {
|
for (const SegmentInformation &segment : description_factory.path_description)
|
||||||
TurnInstruction current_instruction = segment.turn_instruction & TurnInstructionsClass::InverseAccessRestrictionFlag;
|
{
|
||||||
|
TurnInstruction current_instruction =
|
||||||
|
segment.turn_instruction & TurnInstructionsClass::InverseAccessRestrictionFlag;
|
||||||
entered_restricted_area_count += (current_instruction != segment.turn_instruction);
|
entered_restricted_area_count += (current_instruction != segment.turn_instruction);
|
||||||
if (TurnInstructionsClass::TurnIsNecessary( current_instruction) )
|
if (TurnInstructionsClass::TurnIsNecessary(current_instruction))
|
||||||
{
|
{
|
||||||
if (TurnInstructionsClass::EnterRoundAbout == current_instruction)
|
if (TurnInstructionsClass::EnterRoundAbout == current_instruction)
|
||||||
{
|
{
|
||||||
@ -464,19 +451,22 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (0 != necessary_segments_running_index)
|
if (necessary_segments_running_index)
|
||||||
{
|
{
|
||||||
reply.content.push_back(",");
|
reply.content.push_back(",");
|
||||||
}
|
}
|
||||||
reply.content.push_back("[\"");
|
reply.content.push_back("[\"");
|
||||||
if(TurnInstructionsClass::LeaveRoundAbout == current_instruction) {
|
if (TurnInstructionsClass::LeaveRoundAbout == current_instruction)
|
||||||
|
{
|
||||||
intToString(TurnInstructionsClass::EnterRoundAbout, temp_instruction);
|
intToString(TurnInstructionsClass::EnterRoundAbout, temp_instruction);
|
||||||
reply.content.push_back(temp_instruction);
|
reply.content.push_back(temp_instruction);
|
||||||
reply.content.push_back("-");
|
reply.content.push_back("-");
|
||||||
intToString(round_about.leave_at_exit+1, temp_instruction);
|
intToString(round_about.leave_at_exit + 1, temp_instruction);
|
||||||
reply.content.push_back(temp_instruction);
|
reply.content.push_back(temp_instruction);
|
||||||
round_about.leave_at_exit = 0;
|
round_about.leave_at_exit = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
intToString(current_instruction, temp_instruction);
|
intToString(current_instruction, temp_instruction);
|
||||||
reply.content.push_back(temp_instruction);
|
reply.content.push_back(temp_instruction);
|
||||||
}
|
}
|
||||||
@ -490,13 +480,13 @@ public:
|
|||||||
intToString(necessary_segments_running_index, temp_length);
|
intToString(necessary_segments_running_index, temp_length);
|
||||||
reply.content.push_back(temp_length);
|
reply.content.push_back(temp_length);
|
||||||
reply.content.push_back(",");
|
reply.content.push_back(",");
|
||||||
intToString(round(segment.duration/10.), temp_duration);
|
intToString(round(segment.duration / 10.), temp_duration);
|
||||||
reply.content.push_back(temp_duration);
|
reply.content.push_back(temp_duration);
|
||||||
reply.content.push_back(",\"");
|
reply.content.push_back(",\"");
|
||||||
intToString(segment.length, temp_length);
|
intToString(segment.length, temp_length);
|
||||||
reply.content.push_back(temp_length);
|
reply.content.push_back(temp_length);
|
||||||
reply.content.push_back("m\",\"");
|
reply.content.push_back("m\",\"");
|
||||||
double bearing_value = round(segment.bearing/10.);
|
int bearing_value = round(segment.bearing / 10.);
|
||||||
reply.content.push_back(Azimuth::Get(bearing_value));
|
reply.content.push_back(Azimuth::Get(bearing_value));
|
||||||
reply.content.push_back("\",");
|
reply.content.push_back("\",");
|
||||||
intToString(bearing_value, temp_bearing);
|
intToString(bearing_value, temp_bearing);
|
||||||
@ -504,20 +494,20 @@ public:
|
|||||||
reply.content.push_back("]");
|
reply.content.push_back("]");
|
||||||
|
|
||||||
route_segments_list.push_back(
|
route_segments_list.push_back(
|
||||||
Segment(
|
Segment(segment.name_id, segment.length, route_segments_list.size()));
|
||||||
segment.name_id,
|
|
||||||
segment.length,
|
|
||||||
route_segments_list.size()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if(TurnInstructionsClass::StayOnRoundAbout == current_instruction) {
|
}
|
||||||
|
else if (TurnInstructionsClass::StayOnRoundAbout == current_instruction)
|
||||||
|
{
|
||||||
++round_about.leave_at_exit;
|
++round_about.leave_at_exit;
|
||||||
}
|
}
|
||||||
if(segment.necessary)
|
if (segment.necessary)
|
||||||
|
{
|
||||||
++necessary_segments_running_index;
|
++necessary_segments_running_index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(INT_MAX != route_length) {
|
if (INVALID_EDGE_WEIGHT != route_length)
|
||||||
|
{
|
||||||
reply.content.push_back(",[\"");
|
reply.content.push_back(",[\"");
|
||||||
intToString(TurnInstructionsClass::ReachedYourDestination, temp_instruction);
|
intToString(TurnInstructionsClass::ReachedYourDestination, temp_instruction);
|
||||||
reply.content.push_back(temp_instruction);
|
reply.content.push_back(temp_instruction);
|
||||||
@ -525,7 +515,7 @@ public:
|
|||||||
reply.content.push_back("\",");
|
reply.content.push_back("\",");
|
||||||
reply.content.push_back("0");
|
reply.content.push_back("0");
|
||||||
reply.content.push_back(",");
|
reply.content.push_back(",");
|
||||||
intToString(necessary_segments_running_index-1, temp_length);
|
intToString(necessary_segments_running_index - 1, temp_length);
|
||||||
reply.content.push_back(temp_length);
|
reply.content.push_back(temp_length);
|
||||||
reply.content.push_back(",");
|
reply.content.push_back(",");
|
||||||
reply.content.push_back("0");
|
reply.content.push_back("0");
|
||||||
|
Loading…
Reference in New Issue
Block a user