diff --git a/DataStructures/NNGrid.h b/DataStructures/NNGrid.h index 3a56055e1..34c9b62fa 100644 --- a/DataStructures/NNGrid.h +++ b/DataStructures/NNGrid.h @@ -327,7 +327,7 @@ public: return true; } - _Coordinate FindNearestPointOnEdge(const _Coordinate& inputCoordinate) { + void FindNearestNodeInGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) { unsigned fileIndex = GetFileIndexForLatLon(100000*(lat2y(static_cast(inputCoordinate.lat)/100000.)), inputCoordinate.lon); std::vector<_Edge> candidates; double timestamp = get_timestamp(); @@ -336,7 +336,7 @@ public: GetContentsOfFileBucket(fileIndex+i+j, candidates); } } - _Coordinate nearest(numeric_limits::max(), numeric_limits::max()), tmp; + _Coordinate tmp; double dist = numeric_limits::max(); timestamp = get_timestamp(); for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) { @@ -344,13 +344,34 @@ public: double tmpDist = ComputeDistance(inputCoordinate, it->startCoord, it->targetCoord, tmp, &r); if(tmpDist < dist) { dist = tmpDist; - nearest = tmp; + outputCoordinate = tmp; } } - nearest.lat = 100000*(y2lat(static_cast(nearest.lat)/100000.)); - return nearest; + outputCoordinate.lat = 100000*(y2lat(static_cast(outputCoordinate.lat)/100000.)); } + void FindNearestPointOnEdge(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) { + unsigned fileIndex = GetFileIndexForLatLon(100000*(lat2y(static_cast(inputCoordinate.lat)/100000.)), inputCoordinate.lon); + std::vector<_Edge> candidates; + for(int j = -32768; j < (32768+1); j+=32768) { + for(int i = -1; i < 2; i++) { + GetContentsOfFileBucket(fileIndex+i+j, candidates); + } + } + _Coordinate tmp; + double dist = numeric_limits::max(); + for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) { + double r = 0.; + double tmpDist = ComputeDistance(inputCoordinate, it->startCoord, it->targetCoord, tmp, &r); + if(tmpDist < dist) { + dist = tmpDist; + outputCoordinate.lat = round(100000*(y2lat(static_cast(tmp.lat)/100000.))); + outputCoordinate.lon = tmp.lon; + } + } + } + + private: unsigned FillCell(std::vector& entriesWithSameRAMIndex, unsigned fileOffset ) { diff --git a/DataStructures/NodeInformationHelpDesk.h b/DataStructures/NodeInformationHelpDesk.h index 03bc76ee6..add8b8b8c 100644 --- a/DataStructures/NodeInformationHelpDesk.h +++ b/DataStructures/NodeInformationHelpDesk.h @@ -58,8 +58,8 @@ public: NodeID getNumberOfNodes() const { return numberOfNodes; } NodeID getNumberOfNodes2() const { return int2ExtNodeMap->size(); } - inline void findNearestNodeCoordForLatLon(const _Coordinate coord, _Coordinate& result) { - result = readOnlyGrid->FindNearestPointOnEdge(coord); + inline void FindNearestNodeCoordForLatLon(const _Coordinate coord, _Coordinate& result) { + readOnlyGrid->FindNearestNodeInGraph(coord, result); } inline bool FindRoutingStarts(const _Coordinate start, const _Coordinate target, PhantomNodes * phantomNodes) { @@ -67,6 +67,10 @@ public: return true; } + inline void FindNearestPointOnEdge(const _Coordinate & input, _Coordinate& output){ + readOnlyGrid->FindNearestPointOnEdge(input, output); + } + inline void RegisterThread(const unsigned k, const unsigned v) { readOnlyGrid->threadLookup.Add(k, v); } diff --git a/Plugins/LocatePlugin.h b/Plugins/LocatePlugin.h index 2903edce1..40a0053ae 100644 --- a/Plugins/LocatePlugin.h +++ b/Plugins/LocatePlugin.h @@ -28,7 +28,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../DataStructures/NodeInformationHelpDesk.h" /* - * This Plugin locates the nearest point on a street in the road network for a given coordinate. + * This Plugin locates the nearest node in the road network for a given coordinate. */ class LocatePlugin : public BasePlugin { public: @@ -41,7 +41,7 @@ public: delete nodeHelpDesk; } std::string GetDescriptor() { return std::string("locate"); } - std::string GetVersionString() { return std::string("0.2a (DL)"); } + std::string GetVersionString() { return std::string("0.3 (DL)"); } void HandleRequest(std::vector parameters, http::Reply& reply) { //check number of parameters if(parameters.size() != 2) { @@ -58,7 +58,7 @@ public: } //query to helpdesk _Coordinate result; - nodeHelpDesk->findNearestNodeCoordForLatLon(_Coordinate(lat, lon), result); + nodeHelpDesk->FindNearestNodeCoordForLatLon(_Coordinate(lat, lon), result); //Write to stream reply.status = http::Reply::ok; diff --git a/Plugins/NearestPlugin.h b/Plugins/NearestPlugin.h new file mode 100644 index 000000000..6826d2e79 --- /dev/null +++ b/Plugins/NearestPlugin.h @@ -0,0 +1,96 @@ +/* + open source routing machine + Copyright (C) Dennis Luxen, 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 NearestPlugin_H_ +#define NearestPlugin_H_ + +#include + +#include "BasePlugin.h" + +#include "../DataStructures/NodeInformationHelpDesk.h" + +/* + * This Plugin locates the nearest point on a street in the road network for a given coordinate. + */ +class NearestPlugin : public BasePlugin { +public: + NearestPlugin(std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath) { + nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str()); + ifstream nodesInStream(nodesPath.c_str(), ios::binary); + nodeHelpDesk->initNNGrid(nodesInStream); + } + ~NearestPlugin() { + delete nodeHelpDesk; + } + std::string GetDescriptor() { return std::string("nearest"); } + std::string GetVersionString() { return std::string("0.3 (DL)"); } + void HandleRequest(std::vector parameters, http::Reply& reply) { + //check number of parameters + if(parameters.size() != 2) { + reply = http::Reply::stockReply(http::Reply::badRequest); + return; + } + + int lat = static_cast(100000.*atof(parameters[0].c_str())); + int lon = static_cast(100000.*atof(parameters[1].c_str())); + + 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->FindNearestPointOnEdge(_Coordinate(lat, lon), result); + + //Write to stream + reply.status = http::Reply::ok; + reply.content.append(""); + reply.content.append(""); + reply.content.append(""); + + std::stringstream out1; + out1 << setprecision(10); + out1 << "Nearest Place in map to " << lat/100000. << "," << lon/100000. << ""; + reply.content.append(out1.str()); + reply.content.append(""); + + std::stringstream out2; + out2 << setprecision(10); + out2 << "" << result.lon / 100000. << "," << result.lat / 100000. << ""; + reply.content.append(out2.str()); + reply.content.append(""); + reply.content.append(""); + reply.content.append(""); + + reply.headers.resize(3); + reply.headers[0].name = "Content-Length"; + reply.headers[0].value = boost::lexical_cast(reply.content.size()); + reply.headers[1].name = "Content-Type"; + reply.headers[1].value = "application/vnd.google-earth.kml+xml"; + reply.headers[2].name = "Content-Disposition"; + reply.headers[2].value = "attachment; filename=\"placemark.kml\""; + return; + } +private: + NodeInformationHelpDesk * nodeHelpDesk; +}; + +#endif /* NearestPlugin_H_ */ diff --git a/routed.cpp b/routed.cpp index 9c98450c3..10222449e 100644 --- a/routed.cpp +++ b/routed.cpp @@ -33,6 +33,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "Plugins/BasicDescriptor.h" #include "Plugins/HelloWorldPlugin.h" #include "Plugins/LocatePlugin.h" +#include "Plugins/NearestPlugin.h" #include "Plugins/RoutePlugin.h" #include "Util/InputFileUtil.h" @@ -62,11 +63,17 @@ int main (int argc, char *argv[]) BasePlugin * helloWorld = new HelloWorldPlugin(); h.RegisterPlugin(helloWorld); - BasePlugin * locate = new LocatePlugin( - serverConfig.GetParameter("ramIndex"), - serverConfig.GetParameter("fileIndex"), - serverConfig.GetParameter("nodesData")); - h.RegisterPlugin(locate); + BasePlugin * locate = new LocatePlugin( + serverConfig.GetParameter("ramIndex"), + serverConfig.GetParameter("fileIndex"), + serverConfig.GetParameter("nodesData")); + h.RegisterPlugin(locate); + + BasePlugin * nearest = new NearestPlugin( + serverConfig.GetParameter("ramIndex"), + serverConfig.GetParameter("fileIndex"), + serverConfig.GetParameter("nodesData")); + h.RegisterPlugin(nearest); BasePlugin * route = new RoutePlugin( serverConfig.GetParameter("hsgrData"),