mapsme plugin response parser

This commit is contained in:
Lev Dragunov 2015-04-17 13:52:28 +03:00 committed by Alex Zolotarev
parent 22f26e7089
commit cf98d73162
8 changed files with 206 additions and 2 deletions

View file

@ -34,6 +34,9 @@
#define ROUTING_SECRET_UNLOCKING_WORD "?pedestrian"
#define ROUTING_SECRET_LOCKING_WORD "?vehicle"
// TODO (@ldragunov) change to production server address when we will have one.
#define OSRM_ONLINE_SERVER_URL "http://osrm.online.dev.server"
#define READY_FILE_EXTENSION ".ready"
#define RESUME_FILE_EXTENSION ".resume3"
#define DOWNLOADING_FILE_EXTENSION ".downloading3"

View file

@ -11,7 +11,7 @@ CONFIG -= app_bundle
TEMPLATE = app
ROOT_DIR = ..
DEPENDENCIES = map routing search storage indexer platform geometry coding base osrm jansson protobuf tomcrypt succinct stats_client zlib
DEPENDENCIES = map routing search storage indexer platform geometry stats_client coding base osrm jansson protobuf tomcrypt succinct stats_client zlib
macx-*: LIBS *= "-framework Foundation" "-framework IOKit"

View file

@ -0,0 +1,60 @@
#include "online_cross_fetcher.hpp"
#include "platform/http_request.hpp"
#include "base/logging.hpp"
#include "base/string_utils.hpp"
#include "3party/jansson/myjansson.hpp"
#include "std/bind.hpp"
namespace routing
{
bool ParseResponse(const string & serverResponse, vector<m2::PointD> & outPoints)
{
try
{
my::Json parser(serverResponse.c_str());
json_t * countries = json_object_get(parser.get(), "used_mwms");
size_t pointsCount = json_array_size(countries);
outPoints.reserve(pointsCount);
for (size_t i = 0; i < pointsCount; ++i)
{
json_t * pointArray = json_array_get(countries, i);
outPoints.push_back({json_number_value(json_array_get(pointArray, 0)),
json_number_value(json_array_get(pointArray, 1))});
}
return !outPoints.empty();
}
catch (my::Json::Exception)
{
return false;
}
return false;
}
string GenerateOnlineRequest(string const & serverURL, m2::PointD const & startPoint,
m2::PointD const & finalPoint)
{
return serverURL + "/mapsme?loc=" + strings::to_string(startPoint.y) + ',' +
strings::to_string(startPoint.x) + "&loc=" + strings::to_string(finalPoint.y) + ',' +
strings::to_string(finalPoint.x);
}
OnlineCrossFetcher::OnlineCrossFetcher(string const & serverURL, m2::PointD const & startPoint,
m2::PointD const & finalPoint)
: m_request(GenerateOnlineRequest(serverURL, startPoint, finalPoint))
{
LOG(LINFO, ("Check mwms by URL: ", GenerateOnlineRequest(serverURL, startPoint, finalPoint)));
}
vector<m2::PointD> const & OnlineCrossFetcher::GetMwmPoints()
{
m_mwmPoints.clear();
if (!m_request.RunHTTPRequest())
ParseResponse(m_request.server_response(), m_mwmPoints);
return m_mwmPoints;
}
}

View file

@ -0,0 +1,48 @@
#pragma once
#include "3party/Alohalytics/src/http_client.h"
#include "geometry/point2d.hpp"
#include "std/string.hpp"
#include "std/vector.hpp"
namespace routing
{
/// URL string generator for MAPS.ME OSRM server request.
/// \param serverURL http server url with protocol, name and port if needed. For example:
/// http://mail.ru:12345
/// \param startPoint Coordinates of a start point.
/// \param finalPoint Coordinates of a finish point.
/// \return URL for OSRM MAPS.ME server request.
/// \see MapsMePlugin.hpp for REST protocol.
string GenerateOnlineRequest(string const & serverURL, m2::PointD const & startPoint,
m2::PointD const & finalPoint);
/// \brief ParseResponse MAPS.ME OSRM server response parser.
/// \param serverResponse Server response data.
/// \param outPoints Mwm map points.
/// \return true if there are some maps in a server's response.
bool ParseResponse(string const & serverResponse, vector<m2::PointD> & outPoints);
class OnlineCrossFetcher
{
public:
/// \brief OnlineCrossFetcher helper class to make request to online OSRM server
/// and get mwm name list
/// \param serverURL Server URL
/// \param startPoint Start point coordinate
/// \param finalPoint Finish point coordinate
OnlineCrossFetcher(string const & serverURL, m2::PointD const & startPoint,
m2::PointD const & finalPoint);
/// \brief getMwmNames Waits for a server response, and returns mwm names list.
/// \return Mwm names to build route from startPt to finishPt. Empty list if there were errors.
/// \warning Can take a long time while waits a server response.
vector<m2::PointD> const & GetMwmPoints();
private:
alohalytics::HTTPClientPlatformWrapper m_request;
vector<m2::PointD> m_mwmPoints;
};
}

View file

@ -1,3 +1,4 @@
#include "routing/online_cross_fetcher.hpp"
#include "routing/osrm_router.hpp"
#include "routing/turns_generator.hpp"
#include "routing/vehicle_model.hpp"
@ -46,6 +47,41 @@ double const FEATURES_NEAR_TURN_M = 3.0;
namespace
{
class AbsentCountryChecker
{
public:
AbsentCountryChecker(m2::PointD const & startPoint, m2::PointD const & finalPoint,
RoutingIndexManager & indexManager, Index const * index, Route & route)
: m_route(route),
m_index(index),
m_indexManager(indexManager),
m_fetcher(OSRM_ONLINE_SERVER_URL,
{MercatorBounds::XToLon(startPoint.x), MercatorBounds::YToLat(startPoint.y)},
{MercatorBounds::XToLon(finalPoint.x), MercatorBounds::YToLat(finalPoint.y)})
{
}
~AbsentCountryChecker()
{
vector<m2::PointD> const & points = m_fetcher.GetMwmPoints();
for (m2::PointD const & point : points)
{
RoutingMappingPtrT mapping = m_indexManager.GetMappingByPoint(point, m_index);
if (!mapping->IsValid())
{
LOG(LINFO, ("Online recomends to download", mapping->GetName()));
m_route.AddAbsentCountry(mapping->GetName());
}
}
}
private:
Route & m_route;
Index const * m_index;
RoutingIndexManager & m_indexManager;
OnlineCrossFetcher m_fetcher;
};
class Point2Geometry : private noncopyable
{
m2::PointD m_p, m_p1;
@ -634,6 +670,11 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRoute(m2::PointD const & startPoint,
m2::PointD const & startDirection,
m2::PointD const & finalPoint, Route & route)
{
// Experimental feature
#if defined(DEBUG)
AbsentCountryChecker checker(startPoint, finalPoint, m_indexManager, m_pIndex, route);
UNUSED_VALUE(checker);
#endif
my::HighResTimer timer(true);
RoutingMappingPtrT startMapping = m_indexManager.GetMappingByPoint(startPoint, m_pIndex);
RoutingMappingPtrT targetMapping = m_indexManager.GetMappingByPoint(finalPoint, m_pIndex);

View file

@ -17,6 +17,7 @@ SOURCES += \
cross_routing_context.cpp \
features_road_graph.cpp \
nearest_road_pos_finder.cpp \
online_cross_fetcher.cpp \
osrm2feature_map.cpp \
osrm_online_router.cpp \
osrm_router.cpp \
@ -36,6 +37,7 @@ HEADERS += \
cross_routing_context.hpp \
features_road_graph.hpp \
nearest_road_pos_finder.hpp \
online_cross_fetcher.hpp \
osrm2feature_map.hpp \
osrm_data_facade.hpp \
osrm_online_router.hpp \

View file

@ -0,0 +1,49 @@
#include "testing/testing.hpp"
#include "routing/online_cross_fetcher.hpp"
#include "geometry/point2d.hpp"
#include "std/algorithm.hpp"
#include "std/vector.hpp"
using namespace routing;
namespace
{
UNIT_TEST(UrlGeneratorTest)
{
TEST_EQUAL(GenerateOnlineRequest("http://mapsme.test.ru:10012", m2::PointD(37.726536, 55.690105),
m2::PointD(39.902344, 44.527843)),
"http://mapsme.test.ru:10012/mapsme?loc=55.6901,37.7265&loc=44.5278,39.9023",
("Url parsed"));
}
UNIT_TEST(GoodResponseParse)
{
vector<m2::PointD> outPoints;
TEST(ParseResponse(R"({"used_mwms":[[39.522671,94.009263], [37.4809, 67.7244]]})", outPoints),
("Valid response can't be parsed"));
TEST_EQUAL(outPoints.size(), 2, ());
TEST(
find(outPoints.begin(), outPoints.end(), m2::PointD(39.522671, 94.009263)) != outPoints.end(),
("Can't find point in server's response."));
TEST(find(outPoints.begin(), outPoints.end(), m2::PointD(37.4809, 67.7244)) != outPoints.end(),
("Can't find point in server's response."));
}
UNIT_TEST(BadResponseParse)
{
vector<m2::PointD> outPoints;
TEST(!ParseResponse("{\"used_mwms\":[]}", outPoints), ("Inval response should not be parsed"));
TEST_EQUAL(outPoints.size(), 0, ("Found mwm points in invalid request"));
}
UNIT_TEST(GarbadgeInputToResponseParser)
{
vector<m2::PointD> outPoints;
TEST(!ParseResponse("{\"usedsfblbvlshbvldshbvfvmdfknvksvbksvk", outPoints),
("Malformed response should not be processed."));
TEST_EQUAL(outPoints.size(), 0, ("Found mwm points in invalid request"));
}
}

View file

@ -6,7 +6,7 @@ CONFIG -= app_bundle
TEMPLATE = app
ROOT_DIR = ../..
DEPENDENCIES = routing indexer platform geometry coding base osrm protobuf tomcrypt succinct
DEPENDENCIES = routing indexer platform geometry coding base osrm protobuf tomcrypt succinct jansson
macx-*: LIBS *= "-framework Foundation" "-framework IOKit"
@ -22,6 +22,7 @@ SOURCES += \
astar_algorithm_test.cpp \
astar_router_test.cpp \
cross_routing_tests.cpp \
online_cross_fetcher_test.cpp \
osrm_router_test.cpp \
road_graph_builder.cpp \
road_graph_nearest_turns_test.cpp \