Route description are generated

This commit is contained in:
DennisOSRM
2011-11-17 18:04:49 +01:00
parent d874b51419
commit e7439e92ed
6 changed files with 348 additions and 31 deletions
+112
View File
@@ -0,0 +1,112 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#include <boost/foreach.hpp>
#include "../typedefs.h"
#include "DescriptionFactory.h"
DescriptionFactory::DescriptionFactory() { }
DescriptionFactory::~DescriptionFactory() { }
double DescriptionFactory::GetAngleBetweenCoordinates() const {
return 0.;//GetAngleBetweenTwoEdges(previousCoordinate, currentCoordinate, nextCoordinate);
}
void DescriptionFactory::SetStartSegment(const PhantomNode & _startPhantom) {
startPhantom = _startPhantom;
AppendSegment(_startPhantom.location, _PathData(0, _startPhantom.nodeBasedEdgeNameID, 10, _startPhantom.weight1));
}
void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) {
targetPhantom = _targetPhantom;
AppendSegment(_targetPhantom.location, _PathData(0, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1));
}
void DescriptionFactory::AppendSegment(const _Coordinate & coordinate, const _PathData & data ) {
//Segment information has following format:
//["instruction","streetname",length,position,time,"length","earth_direction",azimuth]
//Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5]
//See also: http://developers.cloudmade.com/wiki/navengine/JSON_format
// (_Coordinate & loc, NodeID nam, unsigned len, unsigned dur, short tInstr)
//Is a new instruction necessary?
//yes: data.turnInstruction != 0;
//no: data.turnInstruction == 0;
pathDescription.push_back(SegmentInformation(coordinate, data.nameID, 0, data.durationOfSegment, data.turnInstruction) );
}
void DescriptionFactory::AppendRouteInstructionString(std::string & output) {
output += "[\"Turn left\",\"High Street\",200,0,10,\"200m\",\"NE\",22.5]";
}
void DescriptionFactory::AppendEncodedPolylineString(std::string & output, bool isEncoded) {
if(isEncoded)
pc.printEncodedString(pathDescription, output);
else
pc.printUnencodedString(pathDescription, output);
}
void DescriptionFactory::AppendEncodedPolylineString(std::string &output) {
pc.printEncodedString(pathDescription, output);
}
void DescriptionFactory::AppendUnencodedPolylineString(std::string &output) {
pc.printUnencodedString(pathDescription, output);
}
unsigned DescriptionFactory::Run() {
unsigned entireLength = 0;
/** starts at index 1 */
pathDescription[0].length = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
pathDescription[i].length = ApproximateDistance(pathDescription[i-1].location, pathDescription[i].location);
}
unsigned lengthOfSegment = 0;
unsigned durationOfSegment = 0;
unsigned indexOfSegmentBegin = 0;
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(pathDescription[i].turnInstruction != 0) {
//INFO("Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID);
assert(pathDescription[i].necessary);
lengthOfSegment = 0;
durationOfSegment = 0;
indexOfSegmentBegin = i;
}
}
//Generalize poly line
BOOST_FOREACH(SegmentInformation & segment, pathDescription) {
//TODO: Replace me by real generalization
segment.necessary = true;
}
//fix what needs to be fixed else
return entireLength;
}
+176
View File
@@ -0,0 +1,176 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef DESCRIPTIONFACTORY_H_
#define DESCRIPTIONFACTORY_H_
#include <vector>
#include "../Algorithms/PolylineCompressor.h"
#include "ExtractorStructs.h"
#include "SegmentInformation.h"
/* This class is fed with all way segments in consecutive order
* and produces the description plus the encoded polyline */
class DescriptionFactory {
PolylineCompressor pc;
PhantomNode startPhantom, targetPhantom;
public:
//I know, declaring this public is considered bad. I'm lazy
std::vector <SegmentInformation> pathDescription;
DescriptionFactory();
virtual ~DescriptionFactory();
double GetAngleBetweenCoordinates() const;
void AppendEncodedPolylineString(std::string &output);
void AppendUnencodedPolylineString(std::string &output);
void AppendSegment(const _Coordinate & coordinate, const _PathData & data);
void AppendRouteInstructionString(std::string & output);
void SetStartSegment(const PhantomNode & startPhantom);
void SetEndSegment(const PhantomNode & startPhantom);
void AppendEncodedPolylineString(std::string & output, bool isEncoded);
unsigned Run();
// static inline void getDirectionOfInstruction(double angle, DirectionOfInstruction & dirInst) {
// if(angle >= 23 && angle < 67) {
// dirInst.direction = "southeast";
// dirInst.shortDirection = "SE";
// return;
// }
// if(angle >= 67 && angle < 113) {
// dirInst.direction = "south";
// dirInst.shortDirection = "S";
// return;
// }
// if(angle >= 113 && angle < 158) {
// dirInst.direction = "southwest";
// dirInst.shortDirection = "SW";
// return;
// }
// if(angle >= 158 && angle < 202) {
// dirInst.direction = "west";
// dirInst.shortDirection = "W";
// return;
// }
// if(angle >= 202 && angle < 248) {
// dirInst.direction = "northwest";
// dirInst.shortDirection = "NW";
// return;
// }
// if(angle >= 248 && angle < 292) {
// dirInst.direction = "north";
// dirInst.shortDirection = "N";
// return;
// }
// if(angle >= 292 && angle < 336) {
// dirInst.direction = "northeast";
// dirInst.shortDirection = "NE";
// return;
// }
// dirInst.direction = "East";
// dirInst.shortDirection = "E";
// return;
// }
//
// static inline void getTurnDirectionOfInstruction(double angle, std::string & output) {
// if(angle >= 23 && angle < 67) {
// output = "Turn sharp right";
// // cout << "angle " << angle << "-> " << output << endl;
// return;
// }
// if (angle >= 67 && angle < 113) {
// output = "Turn right";
// // cout << "angle " << angle << "-> " << output << endl;
// return;
// }
// if (angle >= 113 && angle < 158) {
// output = "Bear right";
// // cout << "angle " << angle << "-> " << output << endl;
// return;
// }
//
// if (angle >= 158 && angle < 202) {
// output = "Continue";
// // cout << "angle " << angle << "-> " << output << endl;
// return;
// }
// if (angle >= 202 && angle < 248) {
// output = "Bear left";
// // cout << "angle " << angle << "-> " << output << endl;
// return;
// }
// if (angle >= 248 && angle < 292) {
// output = "Turn left";
// // cout << "angle " << angle << "-> " << output << endl;
// return;
// }
// if (angle >= 292 && angle < 336) {
// output = "Turn sharp left";
// // cout << "angle " << angle << "-> " << output << endl;
// return;
// }
// output = "U-Turn";
// // cout << "angle " << angle << "-> " << output << endl;
// }
//private:
// void appendInstructionNameToString(const std::string & nameOfStreet, const std::string & instructionOrDirection, std::string &output, bool firstAdvice = false) {
// output += "[";
// if(config.instructions) {
// output += "\"";
// if(firstAdvice) {
// output += "Head ";
// }
// output += instructionOrDirection;
// output += "\",\"";
// output += nameOfStreet;
// output += "\",";
// }
// }
//
// void appendInstructionLengthToString(unsigned length, std::string &output) {
// if(config.instructions){
// std::string tmpDistance;
// intToString(10*(round(length/10.)), tmpDistance);
// output += tmpDistance;
// output += ",";
// intToString(descriptionFactory.startIndexOfGeometry, tmp);
// output += tmp;
// output += ",";
// intToString(descriptionFactory.durationOfInstruction, tmp);
// output += tmp;
// output += ",";
// output += "\"";
// output += tmpDistance;
// output += "\",";
// double angle = descriptionFactory.GetAngleBetweenCoordinates();
// DirectionOfInstruction direction;
// getDirectionOfInstruction(angle, direction);
// output += "\"";
// output += direction.shortDirection;
// output += "\",";
// std::stringstream numberString;
// numberString << fixed << setprecision(2) << angle;
// output += numberString.str();
// }
// output += "]";
// }
};
#endif /* DESCRIPTIONFACTORY_H_ */