First round of changes for access=destination enhancements. Not yet

fully functional.
This commit is contained in:
DennisOSRM 2012-03-22 10:25:04 +01:00
parent a558f447cf
commit 3f6cc725d6
10 changed files with 114 additions and 72 deletions

View File

@ -108,6 +108,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdg
edge.data.ignoreInGrid = i->ignoreInGrid();
edge.data.nameID = i->name();
edge.data.type = i->type();
edge.data.isAccessRestricted = i->isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size();
edges.push_back( edge );
if( edge.data.backward ) {
@ -119,7 +120,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdg
}
}
sort( edges.begin(), edges.end() );
std::sort( edges.begin(), edges.end() );
_nodeBasedGraph.reset(new _NodeBasedDynamicGraph( nodes, edges ));
INFO("Converted " << inputEdges.size() << " node-based edges into " << _nodeBasedGraph->GetNumberOfEdges() << " edge-based nodes.");
@ -239,6 +240,11 @@ void EdgeBasedGraphFactory::Run() {
short turnInstruction = AnalyzeTurn(u, v, w);
if(turnInstruction == TurnInstructions.UTurn)
distance += uturnPenalty;
if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) {
distance += TurnInstructions.AccessRestrictionPenaly;
turnInstruction |= TurnInstructions.AccessRestrictionFlag;
}
//distance += heightPenalty;
//distance += ComputeTurnPenalty(u, v, w);
assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID);

View File

@ -56,6 +56,7 @@ private:
bool roundabout:1;
bool ignoreInGrid:1;
short type;
bool isAccessRestricted;
};
struct _EdgeBasedEdgeData {

View File

@ -42,10 +42,10 @@ public:
/** Default constructor. target and weight are set to 0.*/
NodeBasedEdge() :
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false), _ignoreInGrid(false) { assert(false); } //shall not be used.
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false), _ignoreInGrid(false), _accessRestricted(false) { assert(false); } //shall not be used.
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig) :
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra), _ignoreInGrid(ig) { if(ty < 0) {ERR("Type: " << ty);}; }
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig, bool ar) :
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar) { if(ty < 0) {ERR("Type: " << ty);}; }
NodeID target() const {return _target; }
NodeID source() const {return _source; }
@ -58,6 +58,7 @@ public:
bool isLocatable() const { return _type != 14; }
bool isRoundabout() const { return _roundabout; }
bool ignoreInGrid() const { return _ignoreInGrid; }
bool isAccessRestricted() const { return _accessRestricted; }
NodeID _source;
NodeID _target;
@ -68,6 +69,7 @@ public:
short _type;
bool _roundabout;
bool _ignoreInGrid;
bool _accessRestricted;
};
class EdgeBasedEdge {

View File

@ -43,6 +43,11 @@ struct TurnInstructionsClass {
const static short StartAtEndOfStreet = 14;
const static short ReachedYourDestination = 15;
const static short AccessRestrictionFlag = (1<<14);
const static short InverseAccessRestrictionFlag = ~(1<<14);
const static int AccessRestrictionPenaly = 1 << 15; //unrelated to the bit set in the restriction flag
std::string TurnStrings[16];
std::string Ordinals[12];

View File

@ -20,7 +20,7 @@
#include "DescriptionFactory.h"
DescriptionFactory::DescriptionFactory() { }
DescriptionFactory::DescriptionFactory() : entireLength(0) { }
DescriptionFactory::~DescriptionFactory() { }
@ -70,7 +70,7 @@ void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLe
if(0 == pathDescription.size())
return;
unsigned entireLength = 0;
// unsigned entireLength = 0;
/** starts at index 1 */
pathDescription[0].length = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
@ -176,7 +176,7 @@ void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLe
}
}
BuildRouteSummary(entireLength, duration);
// BuildRouteSummary(entireLength, duration);
return;
}

View File

@ -39,7 +39,6 @@ class DescriptionFactory {
PolylineCompressor pc;
PhantomNode startPhantom, targetPhantom;
void BuildRouteSummary(const unsigned distance, const unsigned time);
typedef SearchEngine<ContractionCleanup::Edge::EdgeData, StaticGraph<ContractionCleanup::Edge::EdgeData> > SearchEngineT;
public:
struct _RouteSummary {
@ -60,6 +59,8 @@ public:
}
} summary;
unsigned entireLength;
//I know, declaring this public is considered bad. I'm lazy
std::vector <SegmentInformation> pathDescription;
DescriptionFactory();
@ -68,6 +69,7 @@ public:
void AppendEncodedPolylineString(std::string &output);
void AppendUnencodedPolylineString(std::string &output);
void AppendSegment(const _Coordinate & coordinate, const _PathData & data);
void BuildRouteSummary(const unsigned distance, const unsigned time);
void SetStartSegment(const PhantomNode & startPhantom);
void SetEndSegment(const PhantomNode & startPhantom);
void AppendEncodedPolylineString(std::string & output, bool isEncoded);

View File

@ -37,7 +37,7 @@ private:
_DescriptorConfig config;
DescriptionFactory descriptionFactory;
_Coordinate current;
unsigned numberOfEnteredRestrictedAreas;
struct {
int startIndex;
int nameID;
@ -45,7 +45,7 @@ private:
} roundAbout;
public:
JSONDescriptor() {}
JSONDescriptor() : numberOfEnteredRestrictedAreas(0) {}
void SetConfig(const _DescriptorConfig & c) { config = c; }
void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, const unsigned durationOfTrip) {
@ -68,20 +68,6 @@ public:
}
descriptionFactory.Run(sEngine, config.z, durationOfTrip);
reply.content += "\"route_summary\": {"
"\"total_distance\":";
reply.content += descriptionFactory.summary.lengthString;
reply.content += ","
"\"total_time\":";
reply.content += descriptionFactory.summary.durationString;
reply.content += ","
"\"start_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName);
reply.content += "\","
"\"end_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
reply.content += "\"";
reply.content += "},";
reply.content += "\"route_geometry\": ";
if(config.geometry) {
descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
@ -101,9 +87,11 @@ public:
roundAbout.nameID = 0;
std::string tmpDist, tmpLength, tmpDuration, tmpBearing;
//Fetch data from Factory and generate a string from it.
BOOST_FOREACH(SegmentInformation & segment, descriptionFactory.pathDescription) {
if(TurnInstructions.TurnIsNecessary( segment.turnInstruction) ) {
if(TurnInstructions.EnterRoundAbout == segment.turnInstruction) {
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
if(TurnInstructions.TurnIsNecessary( currentInstruction) ) {
if(TurnInstructions.EnterRoundAbout == currentInstruction) {
roundAbout.nameID = segment.nameID;
roundAbout.startIndex = prefixSumOfNecessarySegments;
} else {
@ -111,14 +99,14 @@ public:
reply.content += ",";
}
reply.content += "[\"";
if(TurnInstructions.LeaveRoundAbout == segment.turnInstruction) {
if(TurnInstructions.LeaveRoundAbout == currentInstruction) {
reply.content += TurnInstructions.TurnStrings[TurnInstructions.EnterRoundAbout];
reply.content += " and leave at ";
reply.content += TurnInstructions.Ordinals[std::min(11,roundAbout.leaveAtExit+1)];
reply.content += " exit";
roundAbout.leaveAtExit = 0;
} else {
reply.content += TurnInstructions.TurnStrings[segment.turnInstruction];
reply.content += TurnInstructions.TurnStrings[currentInstruction];
}
reply.content += "\",\"";
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
@ -141,12 +129,13 @@ public:
reply.content += tmpBearing;
reply.content += "]";
}
} else if(TurnInstructions.StayOnRoundAbout == segment.turnInstruction) {
} else if(TurnInstructions.StayOnRoundAbout == currentInstruction) {
++roundAbout.leaveAtExit;
}
if(segment.necessary)
++prefixSumOfNecessarySegments;
}
reply.content += ",[\"";
reply.content += TurnInstructions.TurnStrings[TurnInstructions.ReachedYourDestination];
reply.content += "\",\"";
@ -163,8 +152,31 @@ public:
reply.content += "\",";
reply.content += "0.0";
reply.content += "]";
} else {
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
}
}
reply.content += "],";
// INFO("Entered " << numberOfEnteredRestrictedAreas << " restricted areas");
descriptionFactory.BuildRouteSummary(descriptionFactory.entireLength, durationOfTrip - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenaly));
reply.content += "\"route_summary\": {"
"\"total_distance\":";
reply.content += descriptionFactory.summary.lengthString;
reply.content += ","
"\"total_time\":";
reply.content += descriptionFactory.summary.durationString;
reply.content += ","
"\"start_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName);
reply.content += "\","
"\"end_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
reply.content += "\"";
reply.content += "},";
//list all viapoints so that the client may display it
reply.content += "\"via_points\":[";
std::string tmp;

View File

@ -98,18 +98,19 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
short type;
NodeID nameID;
int length;
bool isRoundabout, ignoreInGrid;
bool isRoundabout, ignoreInGrid, isAccessRestricted;
for (EdgeID i=0; i<m; ++i) {
in.read((char*)&source, sizeof(unsigned));
in.read((char*)&target, sizeof(unsigned));
in.read((char*)&length, sizeof(int));
in.read((char*)&dir, sizeof(short));
in.read((char*)&weight, sizeof(int));
in.read((char*)&type, sizeof(short));
in.read((char*)&nameID, sizeof(unsigned));
in.read((char*)&isRoundabout, sizeof(bool));
in.read((char*)&ignoreInGrid, sizeof(bool));
in.read((char*)&source, sizeof(unsigned));
in.read((char*)&target, sizeof(unsigned));
in.read((char*)&length, sizeof(int));
in.read((char*)&dir, sizeof(short));
in.read((char*)&weight, sizeof(int));
in.read((char*)&type, sizeof(short));
in.read((char*)&nameID, sizeof(unsigned));
in.read((char*)&isRoundabout, sizeof(bool));
in.read((char*)&ignoreInGrid, sizeof(bool));
in.read((char*)&isAccessRestricted, sizeof(bool));
GUARANTEE(length > 0, "loaded null length edge" );
GUARANTEE(weight > 0, "loaded null weight");
@ -146,7 +147,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
std::swap(forward, backward);
}
EdgeT inputEdge(source, target, nameID, weight, forward, backward, type, isRoundabout, ignoreInGrid );
EdgeT inputEdge(source, target, nameID, weight, forward, backward, type, isRoundabout, ignoreInGrid, isAccessRestricted );
edgeList.push_back(inputEdge);
}
std::sort(edgeList.begin(), edgeList.end());

View File

@ -51,6 +51,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "Util/BaseConfiguration.h"
#include "Util/InputFileUtil.h"
#include "Util/MachineInfo.h"
#include "Util/StringUtil.h"
using namespace std;
@ -129,36 +130,42 @@ int main (int argc, char *argv[]) {
if(name == "obeyOneways") {
if(value == "no")
settings.obeyOneways = false;
} else {
if(name == "obeyBollards") {
if(value == "no") {
settings.obeyBollards = false;
}
} else {
if(name == "useRestrictions") {
if(value == "no")
settings.useRestrictions = false;
} else {
if(name == "accessTag") {
settings.accessTag = value;
} else {
if(name == "excludeFromGrid") {
settings.excludeFromGrid = value;
} else {
if(name == "defaultSpeed") {
settings.defaultSpeed = atoi(value.c_str());
settings.speedProfile["default"] = std::make_pair(settings.defaultSpeed, settings.speedProfile.size() );
} else {
if( name == "takeMinimumOfSpeeds") {
settings.takeMinimumOfSpeeds = ("yes" == value);
}
}
}
}
}
} else if(name == "obeyBollards") {
if(value == "no") {
settings.obeyBollards = false;
}
} else if(name == "useRestrictions") {
if(value == "no")
settings.useRestrictions = false;
} else if(name == "accessTag") {
settings.accessTag = value;
} else if(name == "excludeFromGrid") {
settings.excludeFromGrid = value;
} else if(name == "defaultSpeed") {
settings.defaultSpeed = atoi(value.c_str());
settings.speedProfile["default"] = std::make_pair(settings.defaultSpeed, settings.speedProfile.size() );
} else if( name == "takeMinimumOfSpeeds") {
settings.takeMinimumOfSpeeds = ("yes" == value);
} else if( name == "accessRestrictedService") {
//split value at commas
std::vector<std::string> tokens;
stringSplit(value, ',', tokens);
//put each value into map
BOOST_FOREACH(std::string & s, tokens) {
INFO("adding " << s << " to accessRestrictedService");
settings.accessRestrictedService.insert(std::make_pair(s, true));
}
} else if( name == "accessRestrictionKeys") {
//split value at commas
std::vector<std::string> tokens;
stringSplit(value, ',', tokens);
//put each value into map
BOOST_FOREACH(std::string & s, tokens) {
INFO("adding " << s << " to accessRestrictionKeys");
settings.accessRestrictionKeys.insert(std::make_pair(s, true));
}
settings.speedProfile[name] = std::make_pair(std::atoi(value.c_str()), settings.speedProfile.size() );
}
settings.speedProfile[name] = std::make_pair(std::atoi(value.c_str()), settings.speedProfile.size() );
}
} catch(std::exception& e) {
ERR("caught: " << e.what() );
@ -330,8 +337,8 @@ int main (int argc, char *argv[]) {
continue;
}
if(*usedNodeIDsIT == nodesIT->id) {
if(!settings.obeyBollards && nodesIT->bollard)
nodesIT->bollard = false;
if(!settings.obeyBollards && nodesIT->bollard)
nodesIT->bollard = false;
fout.write((char*)&(*nodesIT), sizeof(_Node));
++usedNodeCounter;
++usedNodeIDsIT;
@ -441,6 +448,7 @@ int main (int argc, char *argv[]) {
fout.write((char*)&edgeIT->nameID, sizeof(unsigned));
fout.write((char*)&edgeIT->isRoundabout, sizeof(bool));
fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool));
fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool));
}
++usedEdgeCounter;
++edgeIT;

View File

@ -23,6 +23,10 @@
excludeFromGrid = ferry
defaultSpeed = 50
trafficSignalPenalty = 5
takeMinimumOfSpeeds = no
uturnPenalty = 20
accessRestrictedService = parking_aisle
accessRestrictionKeys = destination,private
[bike]
trunk = 16
trunk_link = 16
@ -48,4 +52,5 @@
defaultSpeed = 5
trafficSignalPenalty = 5
obeyBollards = no
takeMinimumOfSpeeds = yes
uturnPenalty = 20