Add function cdb_routing_with_waypoints
Add routing with waypoints functions to client and server. Includes signature checks tests for the Postgresql functions and unit and integration tests for the Python library. Add client v0.6.0 and server v0.9.0
This commit is contained in:
@@ -13,8 +13,8 @@ OLD_VERSIONS = $(wildcard old_versions/*.sql)
|
||||
# @see http://www.postgresql.org/docs/current/static/extend-pgxs.html
|
||||
DATA = $(NEW_EXTENSION_ARTIFACT) \
|
||||
$(OLD_VERSIONS) \
|
||||
cdb_dataservices_server--0.7.4--0.8.0.sql \
|
||||
cdb_dataservices_server--0.8.0--0.7.4.sql
|
||||
cdb_dataservices_server--0.8.0--0.9.0.sql \
|
||||
cdb_dataservices_server--0.9.0--0.8.0.sql
|
||||
|
||||
REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql)))
|
||||
TEST_DIR = test/
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.9.0'" to load this file. \quit
|
||||
DROP FUNCTION IF EXISTS cdb_dataservices_server._cdb_mapzen_route_point_to_point(text, text, geometry(Geometry, 4326), geometry(Geometry, 4326), text, text[], text);
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_route_with_waypoints(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
waypoints geometry(Point, 4326)[],
|
||||
mode TEXT,
|
||||
options text[] DEFAULT ARRAY[]::text[],
|
||||
units text DEFAULT 'kilometers')
|
||||
RETURNS cdb_dataservices_server.simple_route AS $$
|
||||
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||
|
||||
mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapzen_route_with_waypoints($1, $2, $3, $4, $5, $6) as route;", ["text", "text", "geometry(Point, 4326)[]", "text", "text[]", "text"])
|
||||
result = plpy.execute(mapzen_plan, [username, orgname, waypoints, mode, options, units])
|
||||
return [result[0]['shape'],result[0]['length'], result[0]['duration']]
|
||||
$$ LANGUAGE plpythonu;
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_route_with_waypoints(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
waypoints geometry(Point, 4326)[],
|
||||
mode TEXT,
|
||||
options text[] DEFAULT ARRAY[]::text[],
|
||||
units text DEFAULT 'kilometers')
|
||||
RETURNS cdb_dataservices_server.simple_route AS $$
|
||||
import json
|
||||
from cartodb_services.mapzen import MapzenRouting, MapzenRoutingResponse
|
||||
from cartodb_services.mapzen.types import polyline_to_linestring
|
||||
from cartodb_services.metrics import QuotaService
|
||||
from cartodb_services.tools import Coordinate
|
||||
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||
|
||||
quota_service = QuotaService(user_routing_config, redis_conn)
|
||||
if not quota_service.check_user_quota():
|
||||
plpy.error('You have reached the limit of your quota')
|
||||
|
||||
try:
|
||||
client = MapzenRouting(user_routing_config.mapzen_api_key)
|
||||
|
||||
if not waypoints or len(waypoints) < 2:
|
||||
plpy.notice("Empty origin or destination")
|
||||
quota_service.increment_empty_service_use()
|
||||
return [None, None, None]
|
||||
|
||||
waypoint_coords = []
|
||||
for idx, points in enumerate(waypoints, start=0):
|
||||
lat = plpy.execute("SELECT ST_Y('%s') AS lat" % waypoints[idx])[0]['lat']
|
||||
lon = plpy.execute("SELECT ST_X('%s') AS lon" % waypoints[idx])[0]['lon']
|
||||
waypoint_coords.append(Coordinate(lon,lat))
|
||||
|
||||
resp = client.calculate_route_point_to_point(waypoint_coords, mode, options, units)
|
||||
if resp and resp.shape:
|
||||
shape_linestring = polyline_to_linestring(resp.shape)
|
||||
if shape_linestring:
|
||||
quota_service.increment_success_service_use()
|
||||
return [shape_linestring, resp.length, resp.duration]
|
||||
else:
|
||||
quota_service.increment_empty_service_use()
|
||||
return [None, None, None]
|
||||
else:
|
||||
quota_service.increment_empty_service_use()
|
||||
return [None, None, None]
|
||||
except BaseException as e:
|
||||
import sys, traceback
|
||||
type_, value_, traceback_ = sys.exc_info()
|
||||
quota_service.increment_failed_service_use()
|
||||
error_msg = 'There was an error trying to obtain route using mapzen provider: {0}'.format(e)
|
||||
plpy.notice(traceback.format_tb(traceback_))
|
||||
plpy.error(error_msg)
|
||||
finally:
|
||||
quota_service.increment_total_service_use()
|
||||
$$ LANGUAGE plpythonu SECURITY DEFINER;
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_route_point_to_point(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
origin geometry(Point, 4326),
|
||||
destination geometry(Point, 4326),
|
||||
mode TEXT,
|
||||
options text[] DEFAULT ARRAY[]::text[],
|
||||
units text DEFAULT 'kilometers')
|
||||
RETURNS cdb_dataservices_server.simple_route AS $$
|
||||
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||
|
||||
waypoints = [origin, destination]
|
||||
mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapzen_route_with_waypoints($1, $2, $3, $4, $5, $6) as route;", ["text", "text", "geometry(Point, 4326)[]", "text", "text[]", "text"])
|
||||
result = plpy.execute(mapzen_plan, [username, orgname, waypoints, mode, options, units])
|
||||
return [result[0]['shape'],result[0]['length'], result[0]['duration']]
|
||||
$$ LANGUAGE plpythonu;
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.8.0'" to load this file. \quit
|
||||
|
||||
DROP FUNCTION IF EXISTS cdb_dataservices_server.cdb_route_with_waypoints(text, text, geometry(Geometry, 4326)[], text, text[], text);
|
||||
DROP FUNCTION IF EXISTS cdb_dataservices_server._cdb_mapzen_route_with_waypoints(text, text, geometry(Geometry, 4326)[], text, text[], text);
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_route_point_to_point(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
origin geometry(Point, 4326),
|
||||
destination geometry(Point, 4326),
|
||||
mode TEXT,
|
||||
options text[] DEFAULT ARRAY[]::text[],
|
||||
units text DEFAULT 'kilometers')
|
||||
RETURNS cdb_dataservices_server.simple_route AS $$
|
||||
import json
|
||||
from cartodb_services.mapzen import MapzenRouting, MapzenRoutingResponse
|
||||
from cartodb_services.mapzen.types import polyline_to_linestring
|
||||
from cartodb_services.metrics import QuotaService
|
||||
from cartodb_services.tools import Coordinate
|
||||
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||
|
||||
quota_service = QuotaService(user_routing_config, redis_conn)
|
||||
if not quota_service.check_user_quota():
|
||||
plpy.error('You have reached the limit of your quota')
|
||||
|
||||
try:
|
||||
client = MapzenRouting(user_routing_config.mapzen_api_key)
|
||||
|
||||
if not origin or not destination:
|
||||
plpy.notice("Empty origin or destination")
|
||||
quota_service.increment_empty_service_use()
|
||||
return [None, None, None]
|
||||
|
||||
orig_lat = plpy.execute("SELECT ST_Y('%s') AS lat" % origin)[0]['lat']
|
||||
orig_lon = plpy.execute("SELECT ST_X('%s') AS lon" % origin)[0]['lon']
|
||||
origin_coordinates = Coordinate(orig_lon, orig_lat)
|
||||
dest_lat = plpy.execute("SELECT ST_Y('%s') AS lat" % destination)[0]['lat']
|
||||
dest_lon = plpy.execute("SELECT ST_X('%s') AS lon" % destination)[0]['lon']
|
||||
dest_coordinates = Coordinate(dest_lon, dest_lat)
|
||||
|
||||
resp = client.calculate_route_point_to_point(origin_coordinates, dest_coordinates, mode, options, units)
|
||||
|
||||
if resp and resp.shape:
|
||||
shape_linestring = polyline_to_linestring(resp.shape)
|
||||
if shape_linestring:
|
||||
quota_service.increment_success_service_use()
|
||||
return [shape_linestring, resp.length, resp.duration]
|
||||
else:
|
||||
quota_service.increment_empty_service_use()
|
||||
return [None, None, None]
|
||||
else:
|
||||
quota_service.increment_empty_service_use()
|
||||
return [None, None, None]
|
||||
except BaseException as e:
|
||||
import sys, traceback
|
||||
type_, value_, traceback_ = sys.exc_info()
|
||||
quota_service.increment_failed_service_use()
|
||||
error_msg = 'There was an error trying to obtain route using mapzen provider: {0}'.format(e)
|
||||
plpy.notice(traceback.format_tb(traceback_))
|
||||
plpy.error(error_msg)
|
||||
finally:
|
||||
quota_service.increment_total_service_use()
|
||||
$$ LANGUAGE plpythonu SECURITY DEFINER;
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_route_point_to_point(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
origin geometry(Point, 4326),
|
||||
destination geometry(Point, 4326),
|
||||
mode TEXT,
|
||||
options text[] DEFAULT ARRAY[]::text[],
|
||||
units text DEFAULT 'kilometers')
|
||||
RETURNS cdb_dataservices_server.simple_route AS $$
|
||||
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||
|
||||
mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapzen_route_point_to_point($1, $2, $3, $4, $5, $6, $7) as route;", ["text", "text", "geometry(Point, 4326)", "geometry(Point, 4326)", "text", "text[]", "text"])
|
||||
result = plpy.execute(mapzen_plan, [username, orgname, origin, destination, mode, options, units])
|
||||
return [result[0]['shape'],result[0]['length'], result[0]['duration']]
|
||||
$$ LANGUAGE plpythonu;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
comment = 'CartoDB dataservices server extension'
|
||||
default_version = '0.8.0'
|
||||
default_version = '0.9.0'
|
||||
requires = 'plpythonu, plproxy, postgis, cdb_geocoder'
|
||||
superuser = true
|
||||
schema = cdb_dataservices_server
|
||||
|
||||
@@ -4,12 +4,10 @@ CREATE TYPE cdb_dataservices_server.simple_route AS (
|
||||
duration integer
|
||||
);
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_route_point_to_point(
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_route_with_waypoints(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
origin geometry(Point, 4326),
|
||||
destination geometry(Point, 4326),
|
||||
waypoints geometry(Point, 4326)[],
|
||||
mode TEXT,
|
||||
options text[] DEFAULT ARRAY[]::text[],
|
||||
units text DEFAULT 'kilometers')
|
||||
@@ -30,20 +28,18 @@ RETURNS cdb_dataservices_server.simple_route AS $$
|
||||
try:
|
||||
client = MapzenRouting(user_routing_config.mapzen_api_key)
|
||||
|
||||
if not origin or not destination:
|
||||
if not waypoints or len(waypoints) < 2:
|
||||
plpy.notice("Empty origin or destination")
|
||||
quota_service.increment_empty_service_use()
|
||||
return [None, None, None]
|
||||
|
||||
orig_lat = plpy.execute("SELECT ST_Y('%s') AS lat" % origin)[0]['lat']
|
||||
orig_lon = plpy.execute("SELECT ST_X('%s') AS lon" % origin)[0]['lon']
|
||||
origin_coordinates = Coordinate(orig_lon, orig_lat)
|
||||
dest_lat = plpy.execute("SELECT ST_Y('%s') AS lat" % destination)[0]['lat']
|
||||
dest_lon = plpy.execute("SELECT ST_X('%s') AS lon" % destination)[0]['lon']
|
||||
dest_coordinates = Coordinate(dest_lon, dest_lat)
|
||||
|
||||
resp = client.calculate_route_point_to_point(origin_coordinates, dest_coordinates, mode, options, units)
|
||||
waypoint_coords = []
|
||||
for waypoint in waypoints:
|
||||
lat = plpy.execute("SELECT ST_Y('%s') AS lat" % waypoint)[0]['lat']
|
||||
lon = plpy.execute("SELECT ST_X('%s') AS lon" % waypoint)[0]['lon']
|
||||
waypoint_coords.append(Coordinate(lon,lat))
|
||||
|
||||
resp = client.calculate_route_point_to_point(waypoint_coords, mode, options, units)
|
||||
if resp and resp.shape:
|
||||
shape_linestring = polyline_to_linestring(resp.shape)
|
||||
if shape_linestring:
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_route_point_to_point(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
origin geometry(Point, 4326),
|
||||
destination geometry(Point, 4326),
|
||||
mode TEXT,
|
||||
options text[] DEFAULT ARRAY[]::text[],
|
||||
units text DEFAULT 'kilometers')
|
||||
RETURNS cdb_dataservices_server.simple_route AS $$
|
||||
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||
|
||||
waypoints = [origin, destination]
|
||||
mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapzen_route_with_waypoints($1, $2, $3, $4, $5, $6) as route;", ["text", "text", "geometry(Point, 4326)[]", "text", "text[]", "text"])
|
||||
result = plpy.execute(mapzen_plan, [username, orgname, waypoints, mode, options, units])
|
||||
return [result[0]['shape'],result[0]['length'], result[0]['duration']]
|
||||
$$ LANGUAGE plpythonu;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_route_with_waypoints(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
waypoints geometry(Point, 4326)[],
|
||||
mode TEXT,
|
||||
options text[] DEFAULT ARRAY[]::text[],
|
||||
units text DEFAULT 'kilometers')
|
||||
RETURNS cdb_dataservices_server.simple_route AS $$
|
||||
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||
|
||||
mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapzen_route_with_waypoints($1, $2, $3, $4, $5, $6) as route;", ["text", "text", "geometry(Point, 4326)[]", "text", "text[]", "text"])
|
||||
result = plpy.execute(mapzen_plan, [username, orgname, waypoints, mode, options, units])
|
||||
return [result[0]['shape'],result[0]['length'], result[0]['duration']]
|
||||
$$ LANGUAGE plpythonu;
|
||||
@@ -1,18 +0,0 @@
|
||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_route_point_to_point(
|
||||
username TEXT,
|
||||
orgname TEXT,
|
||||
origin geometry(Point, 4326),
|
||||
destination geometry(Point, 4326),
|
||||
mode TEXT,
|
||||
options text[] DEFAULT ARRAY[]::text[],
|
||||
units text DEFAULT 'kilometers')
|
||||
RETURNS cdb_dataservices_server.simple_route AS $$
|
||||
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
|
||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||
plpy.execute("SELECT cdb_dataservices_server._get_routing_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
|
||||
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||
|
||||
mapzen_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._cdb_mapzen_route_point_to_point($1, $2, $3, $4, $5, $6, $7) as route;", ["text", "text", "geometry(Point, 4326)", "geometry(Point, 4326)", "text", "text[]", "text"])
|
||||
result = plpy.execute(mapzen_plan, [username, orgname, origin, destination, mode, options, units])
|
||||
return [result[0]['shape'],result[0]['length'], result[0]['duration']]
|
||||
$$ LANGUAGE plpythonu;
|
||||
@@ -0,0 +1,24 @@
|
||||
-- Check for routing point to point signatures
|
||||
SELECT exists(SELECT *
|
||||
FROM pg_proc p
|
||||
INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)
|
||||
WHERE ns.nspname = 'cdb_dataservices_server'
|
||||
AND proname = 'cdb_route_point_to_point'
|
||||
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, geometry, text, text[], text');
|
||||
exists
|
||||
--------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
-- Check for routing waypoint route signatures
|
||||
SELECT exists(SELECT *
|
||||
FROM pg_proc p
|
||||
INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)
|
||||
WHERE ns.nspname = 'cdb_dataservices_server'
|
||||
AND proname = 'cdb_route_with_waypoints'
|
||||
AND oidvectortypes(p.proargtypes) = 'text, text, geometry[], text, text[], text');
|
||||
exists
|
||||
--------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
+7
-4
@@ -5,8 +5,11 @@ SELECT exists(SELECT *
|
||||
WHERE ns.nspname = 'cdb_dataservices_server'
|
||||
AND proname = 'cdb_route_point_to_point'
|
||||
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, geometry, text, text[], text');
|
||||
exists
|
||||
--------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
-- Check for routing waypoint route signatures
|
||||
SELECT exists(SELECT *
|
||||
FROM pg_proc p
|
||||
INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)
|
||||
WHERE ns.nspname = 'cdb_dataservices_server'
|
||||
AND proname = 'cdb_route_with_waypoints'
|
||||
AND oidvectortypes(p.proargtypes) = 'text, text, geometry[], text, text[], text');
|
||||
@@ -1,7 +0,0 @@
|
||||
-- Check for routing point to point signatures
|
||||
SELECT exists(SELECT *
|
||||
FROM pg_proc p
|
||||
INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)
|
||||
WHERE ns.nspname = 'cdb_dataservices_server'
|
||||
AND proname = 'cdb_route_point_to_point'
|
||||
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, geometry, text, text[], text');
|
||||
@@ -33,11 +33,11 @@ class MapzenRouting:
|
||||
self._url = base_url
|
||||
|
||||
@qps_retry
|
||||
def calculate_route_point_to_point(self, origin, destination, mode,
|
||||
def calculate_route_point_to_point(self, waypoints, mode,
|
||||
options=[], units=METRICS_UNITS):
|
||||
parsed_options = self.__parse_options(options)
|
||||
mode_param = self.__parse_mode_param(mode, parsed_options)
|
||||
directions = self.__parse_directions(origin, destination)
|
||||
directions = self.__parse_directions(waypoints)
|
||||
json_request_params = self.__parse_json_parameters(directions,
|
||||
mode_param,
|
||||
units)
|
||||
@@ -67,11 +67,16 @@ class MapzenRouting:
|
||||
|
||||
return json.dumps(json_options)
|
||||
|
||||
def __parse_directions(self, origin, destination):
|
||||
return {"locations": [
|
||||
{"lon": origin.longitude, "lat": origin.latitude},
|
||||
{"lon": destination.longitude, "lat": destination.latitude}
|
||||
]}
|
||||
def __parse_directions(self, waypoints):
|
||||
path = []
|
||||
for idx, point in enumerate(waypoints):
|
||||
if idx == 0 or idx == len(waypoints) - 1:
|
||||
point_type = 'break'
|
||||
else:
|
||||
point_type = 'through'
|
||||
path.append({"lon": str(point.longitude), "lat": str(point.latitude), "type": point_type})
|
||||
|
||||
return {"locations": path}
|
||||
|
||||
def __parse_routing_response(self, response):
|
||||
try:
|
||||
|
||||
@@ -10,7 +10,7 @@ from setuptools import setup, find_packages
|
||||
setup(
|
||||
name='cartodb_services',
|
||||
|
||||
version='0.6.1',
|
||||
version='0.6.2',
|
||||
|
||||
description='CartoDB Services API Python Library',
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ requests_mock.Mocker.TEST_PREFIX = 'test_'
|
||||
@requests_mock.Mocker()
|
||||
class MapzenRoutingTestCase(unittest.TestCase):
|
||||
|
||||
GOOD_SHAPE = [(38.5, -120.2), (43.2, -126.4)]
|
||||
GOOD_SHAPE_SIMPLE = [(38.5, -120.2), (43.2, -126.4)]
|
||||
|
||||
GOOD_RESPONSE = """{{
|
||||
GOOD_RESPONSE_SIMPLE = """{{
|
||||
"id": "ethervoid-route",
|
||||
"trip": {{
|
||||
"status": 0,
|
||||
@@ -51,7 +51,50 @@ class MapzenRoutingTestCase(unittest.TestCase):
|
||||
}}
|
||||
]
|
||||
}}
|
||||
}}""".format(GOOD_SHAPE)
|
||||
}}""".format(GOOD_SHAPE_SIMPLE)
|
||||
|
||||
GOOD_SHAPE_MULTI = [(40.4, -3.7), (40.1, -3.4), (40.6, -3.9)]
|
||||
|
||||
GOOD_RESPONSE_MULTI = """{{
|
||||
"id": "ethervoid-route",
|
||||
"trip": {{
|
||||
"language":"en-US",
|
||||
"summary":{{
|
||||
"length": 1.261,
|
||||
"time": 913
|
||||
}},
|
||||
"locations":[
|
||||
{{
|
||||
"side_of_street":"right",
|
||||
"lon": -3.7,
|
||||
"lat": 40.4,
|
||||
"type":"break"
|
||||
}},
|
||||
{{
|
||||
"lon": -3.4,
|
||||
"lat": 40.1,
|
||||
"type": "through"
|
||||
}},
|
||||
{{
|
||||
"lon": -3.9,
|
||||
"lat": 40.6,
|
||||
"type": "break"
|
||||
}}
|
||||
],
|
||||
"units":"kilometers",
|
||||
"legs":[
|
||||
{{
|
||||
"shape": "_squF~sqU~qy@_ry@_t`B~s`B",
|
||||
"summary": {{
|
||||
"length":1.261,
|
||||
"time":913
|
||||
}}
|
||||
}}
|
||||
],
|
||||
"status_message": "Found route between points",
|
||||
"status": 0
|
||||
}}
|
||||
}}""".format(GOOD_SHAPE_MULTI)
|
||||
|
||||
MALFORMED_RESPONSE = """{"manolo": "escobar"}"""
|
||||
|
||||
@@ -61,23 +104,39 @@ class MapzenRoutingTestCase(unittest.TestCase):
|
||||
|
||||
def test_calculate_simple_routing_with_valid_params(self, req_mock):
|
||||
req_mock.register_uri('GET', requests_mock.ANY,
|
||||
text=self.GOOD_RESPONSE)
|
||||
text=self.GOOD_RESPONSE_SIMPLE)
|
||||
origin = Coordinate('-120.2', '38.5')
|
||||
destination = Coordinate('-126.4', '43.2')
|
||||
response = self.routing.calculate_route_point_to_point(origin,
|
||||
destination,
|
||||
waypoints = [origin, destination]
|
||||
response = self.routing.calculate_route_point_to_point(waypoints,
|
||||
'car')
|
||||
|
||||
self.assertEqual(response.shape, self.GOOD_SHAPE)
|
||||
self.assertEqual(response.shape, self.GOOD_SHAPE_SIMPLE)
|
||||
self.assertEqual(response.length, 444.59)
|
||||
self.assertEqual(response.duration, 16969)
|
||||
|
||||
def test_uknown_mode_raise_exception(self, req_mock):
|
||||
req_mock.register_uri('GET', requests_mock.ANY,
|
||||
text=self.GOOD_RESPONSE)
|
||||
text=self.GOOD_RESPONSE_SIMPLE)
|
||||
origin = Coordinate('-120.2', '38.5')
|
||||
destination = Coordinate('-126.4', '43.2')
|
||||
waypoints = [origin, destination]
|
||||
|
||||
assert_raises(WrongParams,
|
||||
self.routing.calculate_route_point_to_point,
|
||||
origin, destination, 'unknown')
|
||||
waypoints, 'unknown')
|
||||
|
||||
def test_calculate_routing_waypoints_with_valid_params(self, req_mock):
|
||||
req_mock.register_uri('GET', requests_mock.ANY,
|
||||
text=self.GOOD_RESPONSE_MULTI)
|
||||
origin = Coordinate('-3.7', '40.4')
|
||||
pass_through = Coordinate('-3.4', '40.1')
|
||||
destination = Coordinate('-3.9', '40.6')
|
||||
waypoints = [origin, pass_through, destination]
|
||||
|
||||
response = self.routing.calculate_route_point_to_point(waypoints,
|
||||
'walk')
|
||||
|
||||
self.assertEqual(response.length, 1.261)
|
||||
self.assertEqual(response.duration, 913)
|
||||
self.assertEqual(response.shape, self.GOOD_SHAPE_MULTI)
|
||||
|
||||
Reference in New Issue
Block a user