From 8cddaf39c463890dccba359d9bc8ea1d90a55545 Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Fri, 10 Feb 2012 17:14:30 +0100 Subject: [PATCH] Fixes issue #105 and partially #62 as well as #83. --- Contractor/EdgeBasedGraphFactory.cpp | 3 +- DataStructures/NNGrid.h | 3 +- DataStructures/PhantomNodes.h | 4 +- DataStructures/SearchEngine.h | 11 +++++ Descriptors/BaseDescriptor.h | 18 -------- Descriptors/DescriptionFactory.cpp | 34 ++++++++++++-- Descriptors/DescriptionFactory.h | 68 ++++++++++------------------ Descriptors/JSONDescriptor.h | 16 +++---- Util/GraphLoader.h | 2 +- createHierarchy.cpp | 3 +- 10 files changed, 78 insertions(+), 84 deletions(-) diff --git a/Contractor/EdgeBasedGraphFactory.cpp b/Contractor/EdgeBasedGraphFactory.cpp index bca87079d09..1625623e54e 100644 --- a/Contractor/EdgeBasedGraphFactory.cpp +++ b/Contractor/EdgeBasedGraphFactory.cpp @@ -156,7 +156,6 @@ void EdgeBasedGraphFactory::Run() { currentNode.lon2 = inputNodeInfoList[v].lon; currentNode.id = _nodeBasedGraph->GetEdgeData(e1).edgeBasedNodeID; currentNode.ignoreInGrid = _nodeBasedGraph->GetEdgeData(e1).ignoreInGrid; - // short startHeight = srtmLookup.height(currentNode.lon1/100000.,currentNode.lat1/100000. ); // short targetHeight = srtmLookup.height(currentNode.lon2/100000.,currentNode.lat2/100000. ); // short heightDiff = startHeight - targetHeight; @@ -242,6 +241,7 @@ void EdgeBasedGraphFactory::Run() { currentNode.lon2 = inputNodeInfoList[w].lon; currentNode.id = edgeBasedTarget; currentNode.ignoreInGrid = _nodeBasedGraph->GetEdgeData(e2).ignoreInGrid; + INFO("created node #" << edgeBasedNodes.size() << " (" << v << "," << w << ")"); edgeBasedNodes.push_back(currentNode); } @@ -254,7 +254,6 @@ void EdgeBasedGraphFactory::Run() { currentNode.lon2 = inputNodeInfoList[v].lon; currentNode.id = edgeBasedSource; currentNode.ignoreInGrid = _nodeBasedGraph->GetEdgeData(e1).ignoreInGrid; - // short startHeight = srtmLookup.height(currentNode.lon1/100000.,currentNode.lat1/100000. ); // short targetHeight = srtmLookup.height(currentNode.lon2/100000.,currentNode.lat2/100000. ); // short heightDiff = startHeight - targetHeight; diff --git a/DataStructures/NNGrid.h b/DataStructures/NNGrid.h index c151994f105..ef19eb10fa4 100644 --- a/DataStructures/NNGrid.h +++ b/DataStructures/NNGrid.h @@ -148,7 +148,7 @@ class NNGrid { #endif } - bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) { + bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) { bool foundNode = false; _Coordinate startCoord(100000*(lat2y(static_cast(location.lat)/100000.)), location.lon); /** search for point on edge close to source */ @@ -206,6 +206,7 @@ class NNGrid { if(INT_MAX != resultNode.weight2) { resultNode.weight2 -= resultNode.weight1; } + resultNode.ratio = ratio; // INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2); // INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no") << "\n--") return foundNode; diff --git a/DataStructures/PhantomNodes.h b/DataStructures/PhantomNodes.h index 76ba93e1ded..9d9dfe3e3d1 100644 --- a/DataStructures/PhantomNodes.h +++ b/DataStructures/PhantomNodes.h @@ -24,17 +24,19 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "ExtractorStructs.h" struct PhantomNode { - PhantomNode() : edgeBasedNode(UINT_MAX), nodeBasedEdgeNameID(UINT_MAX), weight1(INT_MAX), weight2(INT_MAX) {} + PhantomNode() : edgeBasedNode(UINT_MAX), nodeBasedEdgeNameID(UINT_MAX), weight1(INT_MAX), weight2(INT_MAX), ratio(0.) {} NodeID edgeBasedNode; unsigned nodeBasedEdgeNameID; int weight1; int weight2; + double ratio; _Coordinate location; void Reset() { edgeBasedNode = UINT_MAX; nodeBasedEdgeNameID = UINT_MAX; weight1 = INT_MAX; weight2 = INT_MAX; + ratio = 0.; location.Reset(); } bool isBidirected() const { diff --git a/DataStructures/SearchEngine.h b/DataStructures/SearchEngine.h index 98dda6be71e..1c0f2e4151f 100644 --- a/DataStructures/SearchEngine.h +++ b/DataStructures/SearchEngine.h @@ -334,11 +334,22 @@ class SearchEngine { } } +// INFO("dist: " << _upperbound); if ( _upperbound == INT_MAX ) { return _upperbound; } std::deque packedPath; _RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middle, packedPath); + + + //Setting weights to correspond with that of the actual chosen path + if(packedPath[0] == phantomNodes.startPhantom.edgeBasedNode && phantomNodes.startPhantom.isBidirected()) { +// INFO("Setting weight1=" << phantomNodes.startPhantom.weight1 << " to that of weight2=" << phantomNodes.startPhantom.weight2); + phantomNodes.startPhantom.weight1 = phantomNodes.startPhantom.weight2; + } else { +// INFO("Setting weight2=" << phantomNodes.startPhantom.weight2 << " to that of weight1=" << phantomNodes.startPhantom.weight1); + phantomNodes.startPhantom.weight2 = phantomNodes.startPhantom.weight1; + } // std::cout << "0: "; // for(unsigned i = 0; i < packedPath.size(); ++i) // std::cout << packedPath[i] << " "; diff --git a/Descriptors/BaseDescriptor.h b/Descriptors/BaseDescriptor.h index 759965addbe..6311977c96d 100644 --- a/Descriptors/BaseDescriptor.h +++ b/Descriptors/BaseDescriptor.h @@ -34,24 +34,6 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../Plugins/RawRouteData.h" -struct _RouteSummary { - std::string lengthString; - std::string durationString; - std::string startName; - std::string destName; - _RouteSummary() : lengthString("0"), durationString("0"), startName("unknown street"), destName("unknown street") {} - void BuildDurationAndLengthStrings(unsigned distance, unsigned time) { - //compute distance/duration for route summary - std::ostringstream s; - s << 10*(round(distance/10.)); - lengthString = s.str(); - int travelTime = time/10 + 1; - s.str(""); - s << travelTime; - durationString = s.str(); - } -}; - struct _DescriptorConfig { _DescriptorConfig() : instructions(true), geometry(true), encodeGeometry(false), z(18) {} bool instructions; diff --git a/Descriptors/DescriptionFactory.cpp b/Descriptors/DescriptionFactory.cpp index 3be0fe215b9..62236901f1c 100644 --- a/Descriptors/DescriptionFactory.cpp +++ b/Descriptors/DescriptionFactory.cpp @@ -65,9 +65,10 @@ void DescriptionFactory::AppendUnencodedPolylineString(std::string &output) { pc.printUnencodedString(pathDescription, output); } -unsigned DescriptionFactory::Run(const unsigned zoomLevel) { +void DescriptionFactory::Run(const unsigned zoomLevel, const unsigned duration) { + if(0 == pathDescription.size()) - return 0; + return; unsigned entireLength = 0; /** starts at index 1 */ @@ -94,8 +95,24 @@ unsigned DescriptionFactory::Run(const unsigned zoomLevel) { indexOfSegmentBegin = i; } } - if(pathDescription[0].length == 0){ - pathDescription[0].turnInstruction = 14; + + //Post-processing to remove empty or nearly empty path segments + if(0. == startPhantom.ratio || 0 == pathDescription[0].length) { + pathDescription.erase(pathDescription.begin()); + pathDescription[0].turnInstruction = TurnInstructions.HeadOn; + pathDescription[0].necessary = true; + startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID; + } else { + pathDescription[0].duration *= startPhantom.ratio; + } + if(1. == targetPhantom.ratio || 0 == pathDescription.back().length) { + pathDescription.pop_back(); + pathDescription.back().necessary = true; + pathDescription.back().turnInstruction = TurnInstructions.NoTurn; + targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID; +// INFO("Deleting last turn instruction"); + } else { + pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.ratio); } //Generalize poly line @@ -109,5 +126,12 @@ unsigned DescriptionFactory::Run(const unsigned zoomLevel) { } } - return entireLength; + BuildRouteSummary(entireLength, duration); + return; +} + +void DescriptionFactory::BuildRouteSummary(const unsigned distance, const unsigned time) { + summary.startName = startPhantom.nodeBasedEdgeNameID; + summary.destName = targetPhantom.nodeBasedEdgeNameID; + summary.BuildDurationAndLengthStrings(distance, time); } diff --git a/Descriptors/DescriptionFactory.h b/Descriptors/DescriptionFactory.h index f1c8f4ed67d..6f4e1234b90 100644 --- a/Descriptors/DescriptionFactory.h +++ b/Descriptors/DescriptionFactory.h @@ -28,6 +28,7 @@ #include "../Algorithms/PolylineCompressor.h" #include "../DataStructures/ExtractorStructs.h" #include "../DataStructures/SegmentInformation.h" +#include "../DataStructures/TurnInstructions.h" /* This class is fed with all way segments in consecutive order * and produces the description plus the encoded polyline */ @@ -36,7 +37,28 @@ class DescriptionFactory { DouglasPeucker dp; PolylineCompressor pc; PhantomNode startPhantom, targetPhantom; + + void BuildRouteSummary(const unsigned distance, const unsigned time); + public: + struct _RouteSummary { + std::string lengthString; + std::string durationString; + unsigned startName; + unsigned destName; + _RouteSummary() : lengthString("0"), durationString("0"), startName(0), destName(0) {} + void BuildDurationAndLengthStrings(unsigned distance, unsigned time) { + //compute distance/duration for route summary + std::ostringstream s; + s << 10*(round(distance/10.)); + lengthString = s.str(); + int travelTime = time/10 + 1; + s.str(""); + s << travelTime; + durationString = s.str(); + } + } summary; + //I know, declaring this public is considered bad. I'm lazy std::vector pathDescription; DescriptionFactory(); @@ -48,51 +70,7 @@ class DescriptionFactory { void SetStartSegment(const PhantomNode & startPhantom); void SetEndSegment(const PhantomNode & startPhantom); void AppendEncodedPolylineString(std::string & output, bool isEncoded); - unsigned Run(const unsigned zoomLevel); - + void Run(const unsigned zoomLevel, const unsigned duration); }; #endif /* DESCRIPTIONFACTORY_H_ */ - -//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 += "]"; -// } diff --git a/Descriptors/JSONDescriptor.h b/Descriptors/JSONDescriptor.h index 694cb4e033d..275f629d362 100644 --- a/Descriptors/JSONDescriptor.h +++ b/Descriptors/JSONDescriptor.h @@ -34,7 +34,6 @@ template class JSONDescriptor : public BaseDescriptor{ private: _DescriptorConfig config; - _RouteSummary summary; DescriptionFactory descriptionFactory; _Coordinate current; @@ -51,9 +50,7 @@ class JSONDescriptor : public BaseDescriptor{ void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, const unsigned durationOfTrip) { WriteHeaderToOutput(reply.content); if(durationOfTrip != INT_MAX) { - summary.startName = sEngine.GetEscapedNameForNameID(phantomNodes.startPhantom.nodeBasedEdgeNameID); descriptionFactory.SetStartSegment(phantomNodes.startPhantom); - summary.destName = sEngine.GetEscapedNameForNameID(phantomNodes.targetPhantom.nodeBasedEdgeNameID); reply.content += "0," "\"status_message\": \"Found route between points\","; @@ -69,20 +66,20 @@ class JSONDescriptor : public BaseDescriptor{ "\"status_message\": \"Cannot find route between points\","; } - summary.BuildDurationAndLengthStrings(descriptionFactory.Run(config.z), durationOfTrip); + descriptionFactory.Run(config.z, durationOfTrip); reply.content += "\"route_summary\": {" "\"total_distance\":"; - reply.content += summary.lengthString; + reply.content += descriptionFactory.summary.lengthString; reply.content += "," "\"total_time\":"; - reply.content += summary.durationString; + reply.content += descriptionFactory.summary.durationString; reply.content += "," "\"start_point\":\""; - reply.content += summary.startName; + reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName); reply.content += "\"," "\"end_point\":\""; - reply.content += summary.destName; + reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName); reply.content += "\""; reply.content += "},"; reply.content += "\"route_geometry\": "; @@ -135,8 +132,9 @@ class JSONDescriptor : public BaseDescriptor{ intToString(segment.duration, tmpDuration); reply.content += tmpDuration; reply.content += ",\""; + intToString(segment.length, tmpLength); reply.content += tmpLength; - reply.content += "\",\""; + reply.content += "m\",\""; reply.content += Azimuth::Get(segment.bearing); reply.content += "\","; doubleToStringWithTwoDigitsBehindComma(segment.bearing, tmpBearing); diff --git a/Util/GraphLoader.h b/Util/GraphLoader.h index 099d390ddcc..e2804c5f16c 100644 --- a/Util/GraphLoader.h +++ b/Util/GraphLoader.h @@ -366,7 +366,7 @@ unsigned readHSGRFromStream(istream &in, vector& nodeList, vector in.read((char*) & numberOfNodes, sizeof(unsigned)); nodeList.resize(numberOfNodes + 1); NodeT currentNode; - for(unsigned nodeCounter = 0; nodeCounter < numberOfNodes; ++nodeCounter ) { + for(unsigned nodeCounter = 0; nodeCounter <= numberOfNodes; ++nodeCounter ) { in.read((char*) ¤tNode, sizeof(NodeT)); nodeList[nodeCounter] = currentNode; } diff --git a/createHierarchy.cpp b/createHierarchy.cpp index 17b6e37edd0..78cc90c028d 100644 --- a/createHierarchy.cpp +++ b/createHierarchy.cpp @@ -197,8 +197,7 @@ int main (int argc, char *argv[]) { } //Serialize numberOfNodes, nodes edgeOutFile.write((char*) &numberOfNodes, sizeof(unsigned)); - edgeOutFile.write((char*) &_nodes[0], sizeof(StaticGraph::_StrNode)*(numberOfNodes)); - + edgeOutFile.write((char*) &_nodes[0], sizeof(StaticGraph::_StrNode)*(numberOfNodes+1)); //Serialize number of Edges edgeOutFile.write((char*) &position, sizeof(unsigned));