From 97653cc9599e74f4e712e2204ae87a2585cca4d0 Mon Sep 17 00:00:00 2001 From: Alex Zolotarev Date: Mon, 7 Jul 2014 21:19:55 +0200 Subject: [PATCH] [routing] Added OSRM online engine --- routing/osrm_router.cpp | 106 ++++++++++++++++++++++++++++++++++++++++ routing/osrm_router.hpp | 29 +++++++++++ routing/routing.pro | 4 ++ 3 files changed, 139 insertions(+) create mode 100644 routing/osrm_router.cpp create mode 100644 routing/osrm_router.hpp diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp new file mode 100644 index 0000000000..90111f8e11 --- /dev/null +++ b/routing/osrm_router.cpp @@ -0,0 +1,106 @@ +#include "osrm_router.hpp" +#include "route.hpp" + +#include "../indexer/mercator.hpp" + +#include "../platform/http_request.hpp" + +#include "../base/timer.hpp" +#include "../base/string_utils.hpp" +#include "../base/macros.hpp" +#include "../base/logging.hpp" + +#include "../std/bind.hpp" + +#include "../3party/jansson/myjansson.hpp" + +namespace routing +{ + +char const * OSRM_CAR_ROUTING_URL = "http://router.project-osrm.org/viaroute?output=json&compression=false&"; + +string OsrmRouter::GetName() const +{ + return "osrm"; +} + +void OsrmRouter::SetFinalPoint(m2::PointD const & finalPt) +{ + m_finalPt = finalPt; +} + +void OsrmRouter::CalculateRoute(m2::PointD const & startingPt, ReadyCallback const & callback) +{ + // Construct OSRM url request to get the route + string url = OSRM_CAR_ROUTING_URL; + url += "loc=" + strings::to_string(startingPt.x) + "," + strings::to_string(startingPt.y) + + "&loc=" + strings::to_string(m_finalPt.x) + "," + strings::to_string(m_finalPt.y); + + // Request will be deleted in the callback + downloader::HttpRequest::Get(url, bind(&OsrmRouter::OnRouteReceived, this, _1)); +} + +void OsrmRouter::OnRouteReceived(downloader::HttpRequest & request) +{ + if (request.Status() == downloader::HttpRequest::ECompleted) + { + LOG(LINFO, ("Route HTTP request response:", request.Data())); + + // Parse received json request + try + { + vector route; + string routeName; + + my::Json json(request.Data().c_str()); + json_t const * jgeometry = json_object_get(json.get(), "route_geometry"); + if (jgeometry) + { + for (size_t i = 0; i < json_array_size(jgeometry); ++i) + { + json_t const * jcoords = json_array_get(jgeometry, i); + if (jcoords) + { + json_t const * jlat = json_array_get(jcoords, 0); + json_t const * jlon = json_array_get(jcoords, 1); + if (jlat && jlon) + { + double const lat = json_number_value(jlat); + double const lon = json_number_value(jlon); + route.push_back(m2::PointD(MercatorBounds::LonToX(lon), MercatorBounds::LatToY(lat))); + } + } + } + json_t const * jsummary = json_object_get(json.get(), "route_summary"); + json_t const * jdistance = json_object_get(jsummary, "total_distance"); + json_t const * jtime = json_object_get(jsummary, "total_time"); + if (jdistance && jtime) + { + uint64_t const metres = static_cast(json_number_value(jdistance)); + uint64_t const minutes = static_cast(json_number_value(jtime) / 60.); + routeName = strings::to_string(metres) + " m " + strings::to_string(minutes) + " min"; + } + } + + if (!route.empty()) + { + LOG(LINFO, ("Received route with", route.size(), "points")); + Route result(GetName(), route, routeName + " " + my::FormatCurrentTime()); + m_callback(result); + } + } + catch (my::Json::Exception const & ex) + { + LOG(LERROR, ("Can't parse route json response", ex.Msg())); + } + } + else + { + LOG(LWARNING, ("Route HTTP request has failed", request.Data())); + } + + // Should delete the request to avoid memory leak + delete &request; +} + +} diff --git a/routing/osrm_router.hpp b/routing/osrm_router.hpp new file mode 100644 index 0000000000..480e21fda9 --- /dev/null +++ b/routing/osrm_router.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "router.hpp" + +#include "../geometry/point2d.hpp" + +namespace downloader { class HttpRequest; } + +namespace routing +{ + +class OsrmRouter : public IRouter +{ + m2::PointD m_finalPt; + ReadyCallback m_callback; + + /// Http callback from the server + void OnRouteReceived(downloader::HttpRequest & request); + +protected: + virtual string RoutingUrl() const = 0; + +public: + virtual string GetName() const; + virtual void SetFinalPoint(m2::PointD const & finalPt); + virtual void CalculateRoute(m2::PointD const & startingPt, ReadyCallback const & callback); +}; + +} // namespace routing diff --git a/routing/routing.pro b/routing/routing.pro index 49b04ff25f..d6db8113b4 100644 --- a/routing/routing.pro +++ b/routing/routing.pro @@ -7,11 +7,14 @@ ROOT_DIR = .. include($$ROOT_DIR/common.pri) +INCLUDEPATH += $$ROOT_DIR/3party/jansson/src + SOURCES += \ route.cpp \ routing_engine.cpp \ road_graph.cpp \ helicopter_router.cpp \ + osrm_router.cpp \ HEADERS += \ route.hpp \ @@ -19,3 +22,4 @@ HEADERS += \ router.hpp \ road_graph.hpp \ helicopter_router.hpp \ + osrm_router.hpp \