Use new data facade in all descriptors
This commit is contained in:
parent
427db3f29a
commit
41df92bb93
@ -51,12 +51,13 @@ struct _DescriptorConfig {
|
|||||||
unsigned short z;
|
unsigned short z;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngine &sEngine) = 0;
|
virtual void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, const DataFacadeT * facade) = 0;
|
||||||
virtual void SetConfig(const _DescriptorConfig & config) = 0;
|
virtual void SetConfig(const _DescriptorConfig & config) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -92,126 +92,127 @@ void DescriptionFactory::AppendUnencodedPolylineString(std::string &output) {
|
|||||||
pc.printUnencodedString(pathDescription, output);
|
pc.printUnencodedString(pathDescription, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLevel) {
|
|
||||||
|
|
||||||
if(0 == pathDescription.size())
|
// void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLevel) {
|
||||||
return;
|
|
||||||
|
|
||||||
// unsigned entireLength = 0;
|
// if(0 == pathDescription.size())
|
||||||
/** starts at index 1 */
|
// return;
|
||||||
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 entireLength = 0;
|
||||||
unsigned durationOfSegment = 0;
|
// /** starts at index 1 */
|
||||||
unsigned indexOfSegmentBegin = 0;
|
// pathDescription[0].length = 0;
|
||||||
|
|
||||||
std::string string0 = sEngine.GetEscapedNameForNameID(pathDescription[0].nameID);
|
|
||||||
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) {
|
// for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
||||||
// string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].nameID);
|
// pathDescription[i].length = ApproximateEuclideanDistance(pathDescription[i-1].location, pathDescription[i].location);
|
||||||
// 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].nameID = pathDescription[i].nameID;
|
|
||||||
// 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].nameID = pathDescription[i-1].nameID;
|
|
||||||
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
|
|
||||||
// lastTurn = i;
|
|
||||||
// }
|
|
||||||
// string0 = string1;
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// double lengthOfSegment = 0;
|
||||||
|
// unsigned durationOfSegment = 0;
|
||||||
|
// unsigned indexOfSegmentBegin = 0;
|
||||||
|
|
||||||
for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
// std::string string0 = sEngine.GetEscapedNameForNameID(pathDescription[0].nameID);
|
||||||
entireLength += pathDescription[i].length;
|
// std::string string1;
|
||||||
lengthOfSegment += pathDescription[i].length;
|
|
||||||
durationOfSegment += pathDescription[i].duration;
|
|
||||||
pathDescription[indexOfSegmentBegin].length = lengthOfSegment;
|
|
||||||
pathDescription[indexOfSegmentBegin].duration = durationOfSegment;
|
|
||||||
|
|
||||||
|
|
||||||
if(TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
|
// /*Simplify turn instructions
|
||||||
//SimpleLogger().Write() << "Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID;
|
// Input :
|
||||||
assert(pathDescription[i].necessary);
|
// 10. Turn left on B 36 for 20 km
|
||||||
lengthOfSegment = 0;
|
// 11. Continue on B 35; B 36 for 2 km
|
||||||
durationOfSegment = 0;
|
// 12. Continue on B 36 for 13 km
|
||||||
indexOfSegmentBegin = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// SimpleLogger().Write() << "#segs: " << pathDescription.size();
|
|
||||||
|
|
||||||
//Post-processing to remove empty or nearly empty path segments
|
// becomes:
|
||||||
if(std::numeric_limits<double>::epsilon() > pathDescription.back().length) {
|
// 10. Turn left on B 36 for 35 km
|
||||||
// SimpleLogger().Write() << "#segs: " << pathDescription.size() << ", last ratio: " << targetPhantom.ratio << ", length: " << pathDescription.back().length;
|
// */
|
||||||
if(pathDescription.size() > 2){
|
// //TODO: rework to check only end and start of string.
|
||||||
pathDescription.pop_back();
|
// // stl string is way to expensive
|
||||||
pathDescription.back().necessary = true;
|
|
||||||
pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
|
|
||||||
targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
|
|
||||||
// SimpleLogger().Write() << "Deleting last turn instruction";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.ratio);
|
|
||||||
}
|
|
||||||
if(std::numeric_limits<double>::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;
|
|
||||||
startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID;
|
|
||||||
// SimpleLogger().Write() << "Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pathDescription[0].duration *= startPhantom.ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Generalize poly line
|
// // unsigned lastTurn = 0;
|
||||||
dp.Run(pathDescription, zoomLevel);
|
// // for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
||||||
|
// // string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].nameID);
|
||||||
|
// // 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].nameID = pathDescription[i].nameID;
|
||||||
|
// // 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].nameID = pathDescription[i-1].nameID;
|
||||||
|
// // pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // if (TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
|
||||||
|
// // lastTurn = i;
|
||||||
|
// // }
|
||||||
|
// // string0 = string1;
|
||||||
|
// // }
|
||||||
|
|
||||||
//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);
|
// for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
||||||
return;
|
// 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.nameID;
|
||||||
|
// 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: " << targetPhantom.ratio << ", length: " << pathDescription.back().length;
|
||||||
|
// if(pathDescription.size() > 2){
|
||||||
|
// pathDescription.pop_back();
|
||||||
|
// pathDescription.back().necessary = true;
|
||||||
|
// pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
|
||||||
|
// targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
|
||||||
|
// // SimpleLogger().Write() << "Deleting last turn instruction";
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.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;
|
||||||
|
// startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID;
|
||||||
|
// // SimpleLogger().Write() << "Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// pathDescription[0].duration *= startPhantom.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) {
|
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time) {
|
||||||
summary.startName = startPhantom.nodeBasedEdgeNameID;
|
summary.startName = startPhantom.nodeBasedEdgeNameID;
|
||||||
|
@ -51,12 +51,18 @@ class DescriptionFactory {
|
|||||||
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:
|
public:
|
||||||
struct _RouteSummary {
|
struct RouteSummary {
|
||||||
std::string lengthString;
|
std::string lengthString;
|
||||||
std::string durationString;
|
std::string durationString;
|
||||||
unsigned startName;
|
unsigned startName;
|
||||||
unsigned destName;
|
unsigned destName;
|
||||||
_RouteSummary() : lengthString("0"), durationString("0"), startName(0), destName(0) {}
|
RouteSummary() :
|
||||||
|
lengthString("0"),
|
||||||
|
durationString("0"),
|
||||||
|
startName(0),
|
||||||
|
destName(0)
|
||||||
|
{}
|
||||||
|
|
||||||
void BuildDurationAndLengthStrings(const double distance, const unsigned time) {
|
void BuildDurationAndLengthStrings(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);
|
||||||
@ -79,7 +85,129 @@ public:
|
|||||||
void SetStartSegment(const PhantomNode & startPhantom);
|
void SetStartSegment(const PhantomNode & startPhantom);
|
||||||
void SetEndSegment(const PhantomNode & startPhantom);
|
void SetEndSegment(const PhantomNode & startPhantom);
|
||||||
void AppendEncodedPolylineString(std::string & output, bool isEncoded);
|
void AppendEncodedPolylineString(std::string & output, bool isEncoded);
|
||||||
void Run(const SearchEngine &sEngine, const unsigned zoomLevel);
|
|
||||||
|
template<class DataFacadeT>
|
||||||
|
void Run(const DataFacadeT * facade, const unsigned zoomLevel) {
|
||||||
|
|
||||||
|
if( pathDescription.empty() ) {
|
||||||
|
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 = facade->GetEscapedNameForNameID(pathDescription[0].nameID);
|
||||||
|
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].nameID);
|
||||||
|
// 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].nameID = pathDescription[i].nameID;
|
||||||
|
// 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].nameID = pathDescription[i-1].nameID;
|
||||||
|
// 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.nameID;
|
||||||
|
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: " << targetPhantom.ratio << ", length: " << pathDescription.back().length;
|
||||||
|
if(pathDescription.size() > 2){
|
||||||
|
pathDescription.pop_back();
|
||||||
|
pathDescription.back().necessary = true;
|
||||||
|
pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
|
||||||
|
targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
|
||||||
|
// SimpleLogger().Write() << "Deleting last turn instruction";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.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;
|
||||||
|
startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID;
|
||||||
|
// SimpleLogger().Write() << "Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pathDescription[0].duration *= startPhantom.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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DESCRIPTIONFACTORY_H_ */
|
#endif /* DESCRIPTIONFACTORY_H_ */
|
||||||
|
@ -32,7 +32,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
class GPXDescriptor : public BaseDescriptor{
|
template<class DataFacadeT>
|
||||||
|
class GPXDescriptor : public BaseDescriptor<DataFacadeT> {
|
||||||
private:
|
private:
|
||||||
_DescriptorConfig config;
|
_DescriptorConfig config;
|
||||||
FixedPointCoordinate current;
|
FixedPointCoordinate current;
|
||||||
@ -40,34 +41,63 @@ private:
|
|||||||
std::string tmp;
|
std::string tmp;
|
||||||
public:
|
public:
|
||||||
void SetConfig(const _DescriptorConfig& c) { config = c; }
|
void SetConfig(const _DescriptorConfig& c) { config = c; }
|
||||||
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngine &sEngine) {
|
|
||||||
|
//TODO: reorder parameters
|
||||||
|
void Run(
|
||||||
|
http::Reply & reply,
|
||||||
|
const RawRouteData &rawRoute,
|
||||||
|
PhantomNodes &phantomNodes,
|
||||||
|
const DataFacadeT * facade
|
||||||
|
) {
|
||||||
reply.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
reply.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||||
reply.content += "<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" xmlns=\"http://www.topografix.com/GPX/1/1\" "
|
reply.content +=
|
||||||
|
"<gpx creator=\"OSRM Routing Engine\" version=\"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 += "<metadata><copyright author=\"Project OSRM\"><license>Data (c) OpenStreetMap contributors (ODbL)</license></copyright></metadata>";
|
reply.content +=
|
||||||
|
"<metadata><copyright author=\"Project OSRM\"><license>Data (c)"
|
||||||
|
" OpenStreetMap contributors (ODbL)</license></copyright>"
|
||||||
|
"</metadata>";
|
||||||
reply.content += "<rte>";
|
reply.content += "<rte>";
|
||||||
if(rawRoute.lengthOfShortestPath != INT_MAX && rawRoute.computedShortestPath.size()) {
|
bool found_route = (rawRoute.lengthOfShortestPath != INT_MAX) &&
|
||||||
convertInternalLatLonToString(phantomNodes.startPhantom.location.lat, tmp);
|
(rawRoute.computedShortestPath.size() );
|
||||||
|
if( found_route ) {
|
||||||
|
convertInternalLatLonToString(
|
||||||
|
phantomNodes.startPhantom.location.lat,
|
||||||
|
tmp
|
||||||
|
);
|
||||||
reply.content += "<rtept lat=\"" + tmp + "\" ";
|
reply.content += "<rtept lat=\"" + tmp + "\" ";
|
||||||
convertInternalLatLonToString(phantomNodes.startPhantom.location.lon, tmp);
|
convertInternalLatLonToString(
|
||||||
|
phantomNodes.startPhantom.location.lon,
|
||||||
|
tmp
|
||||||
|
);
|
||||||
reply.content += "lon=\"" + tmp + "\"></rtept>";
|
reply.content += "lon=\"" + tmp + "\"></rtept>";
|
||||||
|
|
||||||
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedShortestPath) {
|
BOOST_FOREACH(
|
||||||
sEngine.GetCoordinatesForNodeID(pathData.node, current);
|
const _PathData & pathData,
|
||||||
|
rawRoute.computedShortestPath
|
||||||
|
) {
|
||||||
|
current = facade->GetCoordinateOfNode(pathData.node);
|
||||||
|
|
||||||
convertInternalLatLonToString(current.lat, tmp);
|
convertInternalLatLonToString(current.lat, tmp);
|
||||||
reply.content += "<rtept lat=\"" + tmp + "\" ";
|
reply.content += "<rtept lat=\"" + tmp + "\" ";
|
||||||
convertInternalLatLonToString(current.lon, tmp);
|
convertInternalLatLonToString(current.lon, tmp);
|
||||||
reply.content += "lon=\"" + tmp + "\"></rtept>";
|
reply.content += "lon=\"" + tmp + "\"></rtept>";
|
||||||
}
|
}
|
||||||
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lat, tmp);
|
convertInternalLatLonToString(
|
||||||
|
phantomNodes.targetPhantom.location.lat,
|
||||||
|
tmp
|
||||||
|
);
|
||||||
reply.content += "<rtept lat=\"" + tmp + "\" ";
|
reply.content += "<rtept lat=\"" + tmp + "\" ";
|
||||||
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lon, tmp);
|
convertInternalLatLonToString(
|
||||||
|
phantomNodes.targetPhantom.location.lon,
|
||||||
|
tmp
|
||||||
|
);
|
||||||
reply.content += "lon=\"" + tmp + "\"></rtept>";
|
reply.content += "lon=\"" + tmp + "\"></rtept>";
|
||||||
}
|
}
|
||||||
reply.content += "</rte></gpx>";
|
reply.content += "</rte></gpx>";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif /* GPX_DESCRIPTOR_H_ */
|
#endif // GPX_DESCRIPTOR_H_
|
||||||
|
@ -41,7 +41,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
class JSONDescriptor : public BaseDescriptor{
|
template<class DataFacadeT>
|
||||||
|
class JSONDescriptor : public BaseDescriptor<DataFacadeT> {
|
||||||
private:
|
private:
|
||||||
_DescriptorConfig config;
|
_DescriptorConfig config;
|
||||||
DescriptionFactory descriptionFactory;
|
DescriptionFactory descriptionFactory;
|
||||||
@ -79,7 +80,12 @@ public:
|
|||||||
JSONDescriptor() : numberOfEnteredRestrictedAreas(0) {}
|
JSONDescriptor() : numberOfEnteredRestrictedAreas(0) {}
|
||||||
void SetConfig(const _DescriptorConfig & c) { config = c; }
|
void SetConfig(const _DescriptorConfig & c) { config = c; }
|
||||||
|
|
||||||
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngine &sEngine) {
|
void Run(
|
||||||
|
http::Reply & reply,
|
||||||
|
const RawRouteData &rawRoute,
|
||||||
|
PhantomNodes &phantomNodes,
|
||||||
|
const DataFacadeT * facade
|
||||||
|
) {
|
||||||
|
|
||||||
WriteHeaderToOutput(reply.content);
|
WriteHeaderToOutput(reply.content);
|
||||||
|
|
||||||
@ -90,7 +96,7 @@ public:
|
|||||||
|
|
||||||
//Get all the coordinates for the computed route
|
//Get all the coordinates for the computed route
|
||||||
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedShortestPath) {
|
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedShortestPath) {
|
||||||
sEngine.GetCoordinatesForNodeID(pathData.node, current);
|
current = facade->GetCoordinateOfNode(pathData.node);
|
||||||
descriptionFactory.AppendSegment(current, pathData );
|
descriptionFactory.AppendSegment(current, pathData );
|
||||||
}
|
}
|
||||||
descriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
|
descriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
|
||||||
@ -100,7 +106,7 @@ public:
|
|||||||
"\"status_message\": \"Cannot find route between points\",";
|
"\"status_message\": \"Cannot find route between points\",";
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptionFactory.Run(sEngine, config.z);
|
descriptionFactory.Run(facade, config.z);
|
||||||
reply.content += "\"route_geometry\": ";
|
reply.content += "\"route_geometry\": ";
|
||||||
if(config.geometry) {
|
if(config.geometry) {
|
||||||
descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
|
descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
|
||||||
@ -112,7 +118,7 @@ public:
|
|||||||
"\"route_instructions\": [";
|
"\"route_instructions\": [";
|
||||||
numberOfEnteredRestrictedAreas = 0;
|
numberOfEnteredRestrictedAreas = 0;
|
||||||
if(config.instructions) {
|
if(config.instructions) {
|
||||||
BuildTextualDescription(descriptionFactory, reply, rawRoute.lengthOfShortestPath, sEngine, shortestSegments);
|
BuildTextualDescription(descriptionFactory, reply, rawRoute.lengthOfShortestPath, facade, shortestSegments);
|
||||||
} else {
|
} else {
|
||||||
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
||||||
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
||||||
@ -131,10 +137,10 @@ public:
|
|||||||
reply.content += descriptionFactory.summary.durationString;
|
reply.content += descriptionFactory.summary.durationString;
|
||||||
reply.content += ","
|
reply.content += ","
|
||||||
"\"start_point\":\"";
|
"\"start_point\":\"";
|
||||||
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName);
|
reply.content += facade->GetEscapedNameForNameID(descriptionFactory.summary.startName);
|
||||||
reply.content += "\","
|
reply.content += "\","
|
||||||
"\"end_point\":\"";
|
"\"end_point\":\"";
|
||||||
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
|
reply.content += facade->GetEscapedNameForNameID(descriptionFactory.summary.destName);
|
||||||
reply.content += "\"";
|
reply.content += "\"";
|
||||||
reply.content += "}";
|
reply.content += "}";
|
||||||
reply.content +=",";
|
reply.content +=",";
|
||||||
@ -145,12 +151,12 @@ public:
|
|||||||
alternateDescriptionFactory.SetStartSegment(phantomNodes.startPhantom);
|
alternateDescriptionFactory.SetStartSegment(phantomNodes.startPhantom);
|
||||||
//Get all the coordinates for the computed route
|
//Get all the coordinates for the computed route
|
||||||
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedAlternativePath) {
|
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedAlternativePath) {
|
||||||
sEngine.GetCoordinatesForNodeID(pathData.node, current);
|
current = facade->GetCoordinateOfNode(pathData.node);
|
||||||
alternateDescriptionFactory.AppendSegment(current, pathData );
|
alternateDescriptionFactory.AppendSegment(current, pathData );
|
||||||
}
|
}
|
||||||
alternateDescriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
|
alternateDescriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
|
||||||
}
|
}
|
||||||
alternateDescriptionFactory.Run(sEngine, config.z);
|
alternateDescriptionFactory.Run(facade, config.z);
|
||||||
|
|
||||||
//give an array of alternative routes
|
//give an array of alternative routes
|
||||||
reply.content += "\"alternative_geometries\": [";
|
reply.content += "\"alternative_geometries\": [";
|
||||||
@ -165,7 +171,13 @@ public:
|
|||||||
reply.content += "[";
|
reply.content += "[";
|
||||||
//Generate instructions for each alternative
|
//Generate instructions for each alternative
|
||||||
if(config.instructions) {
|
if(config.instructions) {
|
||||||
BuildTextualDescription(alternateDescriptionFactory, reply, rawRoute.lengthOfAlternativePath, sEngine, alternativeSegments);
|
BuildTextualDescription(
|
||||||
|
alternateDescriptionFactory,
|
||||||
|
reply,
|
||||||
|
rawRoute.lengthOfAlternativePath,
|
||||||
|
facade,
|
||||||
|
alternativeSegments
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
BOOST_FOREACH(const SegmentInformation & segment, alternateDescriptionFactory.pathDescription) {
|
BOOST_FOREACH(const SegmentInformation & segment, alternateDescriptionFactory.pathDescription) {
|
||||||
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
||||||
@ -187,10 +199,10 @@ public:
|
|||||||
reply.content += alternateDescriptionFactory.summary.durationString;
|
reply.content += alternateDescriptionFactory.summary.durationString;
|
||||||
reply.content += ","
|
reply.content += ","
|
||||||
"\"start_point\":\"";
|
"\"start_point\":\"";
|
||||||
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName);
|
reply.content += facade->GetEscapedNameForNameID(descriptionFactory.summary.startName);
|
||||||
reply.content += "\","
|
reply.content += "\","
|
||||||
"\"end_point\":\"";
|
"\"end_point\":\"";
|
||||||
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
|
reply.content += facade->GetEscapedNameForNameID(descriptionFactory.summary.destName);
|
||||||
reply.content += "\"";
|
reply.content += "\"";
|
||||||
reply.content += "}";
|
reply.content += "}";
|
||||||
}
|
}
|
||||||
@ -198,7 +210,7 @@ public:
|
|||||||
|
|
||||||
//Get Names for both routes
|
//Get Names for both routes
|
||||||
RouteNames routeNames;
|
RouteNames routeNames;
|
||||||
GetRouteNames(shortestSegments, alternativeSegments, sEngine, routeNames);
|
GetRouteNames(shortestSegments, alternativeSegments, facade, routeNames);
|
||||||
|
|
||||||
reply.content += "\"route_name\":[\"";
|
reply.content += "\"route_name\":[\"";
|
||||||
reply.content += routeNames.shortestPathName1;
|
reply.content += routeNames.shortestPathName1;
|
||||||
@ -257,8 +269,13 @@ public:
|
|||||||
reply.content += "}";
|
reply.content += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetRouteNames(std::vector<Segment> & shortestSegments, std::vector<Segment> & alternativeSegments, const SearchEngine &sEngine, RouteNames & routeNames) {
|
// construct routes names
|
||||||
/*** extract names for both alternatives ***/
|
void GetRouteNames(
|
||||||
|
std::vector<Segment> & shortestSegments,
|
||||||
|
std::vector<Segment> & alternativeSegments,
|
||||||
|
const DataFacadeT * facade,
|
||||||
|
RouteNames & routeNames
|
||||||
|
) {
|
||||||
|
|
||||||
Segment shortestSegment1, shortestSegment2;
|
Segment shortestSegment1, shortestSegment2;
|
||||||
Segment alternativeSegment1, alternativeSegment2;
|
Segment alternativeSegment1, alternativeSegment2;
|
||||||
@ -301,11 +318,19 @@ public:
|
|||||||
if(alternativeSegment1.position > alternativeSegment2.position)
|
if(alternativeSegment1.position > alternativeSegment2.position)
|
||||||
std::swap(alternativeSegment1, alternativeSegment2);
|
std::swap(alternativeSegment1, alternativeSegment2);
|
||||||
|
|
||||||
routeNames.shortestPathName1 = sEngine.GetEscapedNameForNameID(shortestSegment1.nameID);
|
routeNames.shortestPathName1 = facade->GetEscapedNameForNameID(
|
||||||
routeNames.shortestPathName2 = sEngine.GetEscapedNameForNameID(shortestSegment2.nameID);
|
shortestSegment1.nameID
|
||||||
|
);
|
||||||
|
routeNames.shortestPathName2 = facade->GetEscapedNameForNameID(
|
||||||
|
shortestSegment2.nameID
|
||||||
|
);
|
||||||
|
|
||||||
routeNames.alternativePathName1 = sEngine.GetEscapedNameForNameID(alternativeSegment1.nameID);
|
routeNames.alternativePathName1 = facade->GetEscapedNameForNameID(
|
||||||
routeNames.alternativePathName2 = sEngine.GetEscapedNameForNameID(alternativeSegment2.nameID);
|
alternativeSegment1.nameID
|
||||||
|
);
|
||||||
|
routeNames.alternativePathName2 = facade->GetEscapedNameForNameID(
|
||||||
|
alternativeSegment2.nameID
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +340,14 @@ public:
|
|||||||
"\"status\":";
|
"\"status\":";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BuildTextualDescription(DescriptionFactory & descriptionFactory, http::Reply & reply, const int lengthOfRoute, const SearchEngine &sEngine, std::vector<Segment> & segmentVector) {
|
//TODO: reorder parameters
|
||||||
|
inline void BuildTextualDescription(
|
||||||
|
DescriptionFactory & descriptionFactory,
|
||||||
|
http::Reply & reply,
|
||||||
|
const int lengthOfRoute,
|
||||||
|
const DataFacadeT * facade,
|
||||||
|
std::vector<Segment> & segmentVector
|
||||||
|
) {
|
||||||
//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]
|
||||||
@ -351,7 +383,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
reply.content += "\",\"";
|
reply.content += "\",\"";
|
||||||
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
|
reply.content += facade->GetEscapedNameForNameID(segment.nameID);
|
||||||
reply.content += "\",";
|
reply.content += "\",";
|
||||||
intToString(segment.length, tmpDist);
|
intToString(segment.length, tmpDist);
|
||||||
reply.content += tmpDist;
|
reply.content += tmpDist;
|
||||||
|
Loading…
Reference in New Issue
Block a user