From cacf8f17d345a0f66ae86a9fe44ce8ca4eb7c356 Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Thu, 3 May 2012 23:48:20 +0200 Subject: [PATCH 1/2] First implementation. Needs sanity checks if nothing is found. --- Plugins/NearestPlugin.h | 44 ++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/Plugins/NearestPlugin.h b/Plugins/NearestPlugin.h index 8f50dbed2..d2afdc2b0 100644 --- a/Plugins/NearestPlugin.h +++ b/Plugins/NearestPlugin.h @@ -37,31 +37,41 @@ or see http://www.gnu.org/licenses/agpl.txt. */ class NearestPlugin : public BasePlugin { public: - NearestPlugin(QueryObjectsStorage * objects) { + NearestPlugin(QueryObjectsStorage * objects) : names(objects->names) { nodeHelpDesk = objects->nodeHelpDesk; + descriptorTable.Set("", 0); //default descriptor - descriptorTable.Set("kml", 0); descriptorTable.Set("json", 1); } std::string GetDescriptor() const { return std::string("nearest"); } std::string GetVersionString() const { return std::string("0.3 (DL)"); } void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { + INFO("1"); //check number of parameters - if(routeParameters.parameters.size() != 2) { + if(!routeParameters.viaPoints.size()) { reply = http::Reply::stockReply(http::Reply::badRequest); + INFO("2, size: " << routeParameters.viaPoints.size()); return; } + std::vector textCoord; + stringSplit (routeParameters.viaPoints[0], ',', textCoord); + if(textCoord.size() != 2) { + reply = http::Reply::stockReply(http::Reply::badRequest); + return; + } - int lat = static_cast(100000.*atof(routeParameters.parameters[0].c_str())); - int lon = static_cast(100000.*atof(routeParameters.parameters[1].c_str())); - - if(lat>90*100000 || lat <-90*100000 || lon>180*100000 || lon <-180*100000) { + int lat = 100000.*atof(textCoord[0].c_str()); + int lon = 100000.*atof(textCoord[1].c_str()); + _Coordinate myCoordinate(lat, lon); + if(false == checkCoord(myCoordinate)) { reply = http::Reply::stockReply(http::Reply::badRequest); + INFO("3"); return; } + INFO("4"); //query to helpdesk - _Coordinate result; - nodeHelpDesk->FindNearestPointOnEdge(_Coordinate(lat, lon), result); + PhantomNode result; + nodeHelpDesk->FindPhantomNodeForCoordinate(myCoordinate, result); std::string tmp; std::string JSONParameter; @@ -78,13 +88,15 @@ public: reply.content += ("\"version\":0.3,"); reply.content += ("\"status\":0,"); reply.content += ("\"result\":"); - convertInternalLatLonToString(result.lat, tmp); + convertInternalLatLonToString(result.location.lat, tmp); reply.content += "["; reply.content += tmp; - convertInternalLatLonToString(result.lon, tmp); + convertInternalLatLonToString(result.location.lon, tmp); reply.content += ", "; reply.content += tmp; - reply.content += "]"; + reply.content += "], \"name\": \""; + reply.content += names[result.nodeBasedEdgeNameID]; + reply.content += "\""; reply.content += ",\"transactionId\": \"OSRM Routing Engine JSON Nearest (v0.3)\""; reply.content += ("}"); reply.headers.resize(3); @@ -105,8 +117,16 @@ public: reply.headers[0].value = tmp; } private: + inline bool checkCoord(const _Coordinate & c) { + if(c.lat > 90*100000 || c.lat < -90*100000 || c.lon > 180*100000 || c.lon <-180*100000) { + return false; + } + return true; + } + NodeInformationHelpDesk * nodeHelpDesk; HashTable descriptorTable; + std::vector & names; }; #endif /* NearestPlugin_H_ */ From c4f213f64e15b28118badae961808002fd06f6a9 Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Fri, 4 May 2012 14:49:30 +0200 Subject: [PATCH 2/2] Implements issue #173 --- DataStructures/NNGrid.h | 5 +- DataStructures/NodeInformationHelpDesk.h | 8 +-- Plugins/LocatePlugin.h | 84 ++++++++++++++---------- Plugins/NearestPlugin.h | 32 +++++---- 4 files changed, 76 insertions(+), 53 deletions(-) diff --git a/DataStructures/NNGrid.h b/DataStructures/NNGrid.h index a7bdca071..90dd1817b 100644 --- a/DataStructures/NNGrid.h +++ b/DataStructures/NNGrid.h @@ -231,7 +231,8 @@ public: FindPhantomNodeForCoordinate( target, routingStarts.targetPhantom) ); } - void FindNearestCoordinateOnEdgeInNodeBasedGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) { + bool FindNearestCoordinateOnEdgeInNodeBasedGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) { + bool found = false; unsigned fileIndex = GetFileIndexForLatLon(100000*(lat2y(static_cast(inputCoordinate.lat)/100000.)), inputCoordinate.lon); std::vector<_GridEdge> candidates; boost::unordered_map< unsigned, unsigned, IdenticalHashFunction > cellMap; @@ -246,11 +247,13 @@ public: double r = 0.; double tmpDist = ComputeDistance(inputCoordinate, candidate.startCoord, candidate.targetCoord, tmp, &r); if(tmpDist < dist) { + found = true; dist = tmpDist; outputCoordinate = tmp; } } outputCoordinate.lat = 100000*(y2lat(static_cast(outputCoordinate.lat)/100000.)); + return found; } void FindNearestPointOnEdge(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) { diff --git a/DataStructures/NodeInformationHelpDesk.h b/DataStructures/NodeInformationHelpDesk.h index f01e6f3c0..044280f40 100644 --- a/DataStructures/NodeInformationHelpDesk.h +++ b/DataStructures/NodeInformationHelpDesk.h @@ -92,11 +92,11 @@ public: inline NodeID getNumberOfNodes() const { return numberOfNodes; } inline NodeID getNumberOfNodes2() const { return coordinateVector.size(); } - inline void FindNearestNodeCoordForLatLon(const _Coordinate& coord, _Coordinate& result) const { - readOnlyGrid->FindNearestCoordinateOnEdgeInNodeBasedGraph(coord, result); + inline bool FindNearestNodeCoordForLatLon(const _Coordinate& coord, _Coordinate& result) const { + return readOnlyGrid->FindNearestCoordinateOnEdgeInNodeBasedGraph(coord, result); } - inline void FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) const { - readOnlyGrid->FindPhantomNodeForCoordinate(location, resultNode); + inline bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) const { + return readOnlyGrid->FindPhantomNodeForCoordinate(location, resultNode); } inline void FindRoutingStarts(const _Coordinate &start, const _Coordinate &target, PhantomNodes & phantomNodes) const { diff --git a/Plugins/LocatePlugin.h b/Plugins/LocatePlugin.h index dbf2dbf0e..9b73674c2 100644 --- a/Plugins/LocatePlugin.h +++ b/Plugins/LocatePlugin.h @@ -37,28 +37,32 @@ public: LocatePlugin(QueryObjectsStorage * objects) { nodeHelpDesk = objects->nodeHelpDesk; } - std::string GetDescriptor() const { return std::string("locate"); } - std::string GetVersionString() const { return std::string("0.3 (DL)"); } - void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { - //check number of parameters - if(routeParameters.parameters.size() != 2) { - reply = http::Reply::stockReply(http::Reply::badRequest); - return; - } + std::string GetDescriptor() const { return std::string("locate"); } + std::string GetVersionString() const { return std::string("0.3 (DL)"); } + void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { + //check number of parameters + if(!routeParameters.viaPoints.size()) { + reply = http::Reply::stockReply(http::Reply::badRequest); + return; + } + std::vector textCoord; + stringSplit (routeParameters.viaPoints[0], ',', textCoord); + if(textCoord.size() != 2) { + reply = http::Reply::stockReply(http::Reply::badRequest); + return; + } - int lat = static_cast(100000.*atof(routeParameters.parameters[0].c_str())); - int lon = static_cast(100000.*atof(routeParameters.parameters[1].c_str())); + int lat = 100000.*atof(textCoord[0].c_str()); + int lon = 100000.*atof(textCoord[1].c_str()); + _Coordinate myCoordinate(lat, lon); + if(false == checkCoord(myCoordinate)) { + reply = http::Reply::stockReply(http::Reply::badRequest); + return; + } - if(lat>90*100000 || lat <-90*100000 || lon>180*100000 || lon <-180*100000) { - reply = http::Reply::stockReply(http::Reply::badRequest); - return; - } - //query to helpdesk - _Coordinate result; - nodeHelpDesk->FindNearestNodeCoordForLatLon(_Coordinate(lat, lon), result); - - std::string tmp; - std::string JSONParameter; + //query to helpdesk + _Coordinate result; + std::string JSONParameter, tmp; //json JSONParameter = routeParameters.options.Find("jsonp"); @@ -66,20 +70,25 @@ public: reply.content += JSONParameter; reply.content += "("; } - - //Write to stream reply.status = http::Reply::ok; reply.content += ("{"); reply.content += ("\"version\":0.3,"); - reply.content += ("\"status\":0,"); - reply.content += ("\"result\":"); - convertInternalLatLonToString(result.lat, tmp); - reply.content += "["; - reply.content += tmp; - convertInternalLatLonToString(result.lon, tmp); - reply.content += ", "; - reply.content += tmp; - reply.content += "]"; + if(!nodeHelpDesk->FindNearestNodeCoordForLatLon(myCoordinate, result)) { + reply.content += ("\"status\":207,"); + reply.content += ("\"mapped_coordinate\":[]"); + } else { + //Write coordinate to stream + reply.status = http::Reply::ok; + reply.content += ("\"status\":0,"); + reply.content += ("\"mapped_coordinate\":"); + convertInternalLatLonToString(result.lat, tmp); + reply.content += "["; + reply.content += tmp; + convertInternalLatLonToString(result.lon, tmp); + reply.content += ","; + reply.content += tmp; + reply.content += "]"; + } reply.content += ",\"transactionId\": \"OSRM Routing Engine JSON Locate (v0.3)\""; reply.content += ("}"); reply.headers.resize(3); @@ -98,10 +107,17 @@ public: reply.headers[0].name = "Content-Length"; intToString(reply.content.size(), tmp); reply.headers[0].value = tmp; - return; - } + return; + } private: - NodeInformationHelpDesk * nodeHelpDesk; + inline bool checkCoord(const _Coordinate & c) { + if(c.lat > 90*100000 || c.lat < -90*100000 || c.lon > 180*100000 || c.lon <-180*100000) { + return false; + } + return true; + } + + NodeInformationHelpDesk * nodeHelpDesk; }; #endif /* LOCATEPLUGIN_H_ */ diff --git a/Plugins/NearestPlugin.h b/Plugins/NearestPlugin.h index d2afdc2b0..67d0219d0 100644 --- a/Plugins/NearestPlugin.h +++ b/Plugins/NearestPlugin.h @@ -46,11 +46,9 @@ public: std::string GetDescriptor() const { return std::string("nearest"); } std::string GetVersionString() const { return std::string("0.3 (DL)"); } void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { - INFO("1"); //check number of parameters if(!routeParameters.viaPoints.size()) { reply = http::Reply::stockReply(http::Reply::badRequest); - INFO("2, size: " << routeParameters.viaPoints.size()); return; } std::vector textCoord; @@ -65,10 +63,8 @@ public: _Coordinate myCoordinate(lat, lon); if(false == checkCoord(myCoordinate)) { reply = http::Reply::stockReply(http::Reply::badRequest); - INFO("3"); return; } - INFO("4"); //query to helpdesk PhantomNode result; nodeHelpDesk->FindPhantomNodeForCoordinate(myCoordinate, result); @@ -86,18 +82,26 @@ public: reply.status = http::Reply::ok; reply.content += ("{"); reply.content += ("\"version\":0.3,"); - reply.content += ("\"status\":0,"); - reply.content += ("\"result\":"); - convertInternalLatLonToString(result.location.lat, tmp); + reply.content += ("\"status\":"); + if(UINT_MAX != result.edgeBasedNode) + reply.content += "0,"; + else + reply.content += "207,"; + reply.content += ("\"mapped_coordinate\":"); reply.content += "["; - reply.content += tmp; - convertInternalLatLonToString(result.location.lon, tmp); - reply.content += ", "; - reply.content += tmp; - reply.content += "], \"name\": \""; - reply.content += names[result.nodeBasedEdgeNameID]; + if(UINT_MAX != result.edgeBasedNode) { + convertInternalLatLonToString(result.location.lat, tmp); + reply.content += tmp; + convertInternalLatLonToString(result.location.lon, tmp); + reply.content += ","; + reply.content += tmp; + } + reply.content += "],"; + reply.content += "\"name\":\""; + if(UINT_MAX != result.edgeBasedNode) + reply.content += names[result.nodeBasedEdgeNameID]; reply.content += "\""; - reply.content += ",\"transactionId\": \"OSRM Routing Engine JSON Nearest (v0.3)\""; + reply.content += ",\"transactionId\":\"OSRM Routing Engine JSON Nearest (v0.3)\""; reply.content += ("}"); reply.headers.resize(3); if("" != JSONParameter) {