Merge pull request #189 from CartoDB/development
Add routing_with_waypoints functions to Data Services API
This commit is contained in:
commit
b33d696817
@ -78,6 +78,7 @@ Steps to deploy a new Data Services API version :
|
|||||||
SELECT CDB_Conf_SetConf('user_config', '{"is_organization": false, "entity_name": "<YOUR_USERNAME>"}')
|
SELECT CDB_Conf_SetConf('user_config', '{"is_organization": false, "entity_name": "<YOUR_USERNAME>"}')
|
||||||
SELECT CDB_Conf_SetConf('mapzen_conf', '{"routing": {"api_key": "valhalla_app_key", "monthly_quota": 999999}, "geocoder": {"api_key": "search_app_key", "monthly_quota": 999999}}');
|
SELECT CDB_Conf_SetConf('mapzen_conf', '{"routing": {"api_key": "valhalla_app_key", "monthly_quota": 999999}, "geocoder": {"api_key": "search_app_key", "monthly_quota": 999999}}');
|
||||||
SELECT CDB_Conf_SetConf('logger_con', '{"geocoder_log_path": "/tmp/geocodings.log"}')
|
SELECT CDB_Conf_SetConf('logger_con', '{"geocoder_log_path": "/tmp/geocodings.log"}')
|
||||||
|
SELECT CDB_Conf_SetConf('data_observatory_conf', '{"connection": {"whitelist": [], "production": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}}')
|
||||||
```
|
```
|
||||||
|
|
||||||
- configure plproxy to point to the a database (you can use a specific database for the server or your same user)
|
- configure plproxy to point to the a database (you can use a specific database for the server or your same user)
|
||||||
|
@ -13,8 +13,8 @@ OLD_VERSIONS = $(wildcard old_versions/*.sql)
|
|||||||
# @see http://www.postgresql.org/docs/current/static/extend-pgxs.html
|
# @see http://www.postgresql.org/docs/current/static/extend-pgxs.html
|
||||||
DATA = $(NEW_EXTENSION_ARTIFACT) \
|
DATA = $(NEW_EXTENSION_ARTIFACT) \
|
||||||
$(OLD_VERSIONS) \
|
$(OLD_VERSIONS) \
|
||||||
cdb_dataservices_client--0.4.0--0.5.0.sql \
|
cdb_dataservices_client--0.5.0--0.6.0.sql \
|
||||||
cdb_dataservices_client--0.5.0--0.4.0.sql
|
cdb_dataservices_client--0.6.0--0.5.0.sql
|
||||||
|
|
||||||
|
|
||||||
REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql)))
|
REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql)))
|
||||||
|
44
client/cdb_dataservices_client--0.5.0--0.6.0.sql
Normal file
44
client/cdb_dataservices_client--0.5.0--0.6.0.sql
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
--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_client UPDATE TO '0.6.0'" to load this file. \quit
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Public dataservices API function
|
||||||
|
--
|
||||||
|
-- These are the only ones with permissions to publicuser role
|
||||||
|
-- and should also be the only ones with SECURITY DEFINER
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_client.cdb_route_with_waypoints (waypoints geometry(Point, 4326)[], mode text, options text[] DEFAULT ARRAY[]::text[], units text DEFAULT 'kilometers')
|
||||||
|
RETURNS cdb_dataservices_client.simple_route AS $$
|
||||||
|
DECLARE
|
||||||
|
ret cdb_dataservices_client.simple_route;
|
||||||
|
username text;
|
||||||
|
orgname text;
|
||||||
|
BEGIN
|
||||||
|
IF session_user = 'publicuser' OR session_user ~ 'cartodb_publicuser_*' THEN
|
||||||
|
RAISE EXCEPTION 'The api_key must be provided';
|
||||||
|
END IF;
|
||||||
|
SELECT u, o INTO username, orgname FROM cdb_dataservices_client._cdb_entity_config() AS (u text, o text);
|
||||||
|
-- JSON value stored "" is taken as literal
|
||||||
|
IF username IS NULL OR username = '' OR username = '""' THEN
|
||||||
|
RAISE EXCEPTION 'Username is a mandatory argument, check it out';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT * FROM cdb_dataservices_client._cdb_route_with_waypoints(username, orgname, waypoints, mode, options, units) INTO ret;
|
||||||
|
RETURN ret;
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_client._cdb_route_with_waypoints (username text, organization_name text, waypoints geometry(Point, 4326)[], mode text, options text[] DEFAULT ARRAY[]::text[], units text DEFAULT 'kilometers')
|
||||||
|
RETURNS cdb_dataservices_client.simple_route AS $$
|
||||||
|
CONNECT cdb_dataservices_client._server_conn_str();
|
||||||
|
|
||||||
|
SELECT * FROM cdb_dataservices_server.cdb_route_with_waypoints (username, organization_name, waypoints, mode, options, units);
|
||||||
|
|
||||||
|
$$ LANGUAGE plproxy;
|
||||||
|
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.cdb_route_with_waypoints(waypoints geometry(Point, 4326)[], mode text, options text[], units text) TO publicuser;
|
5
client/cdb_dataservices_client--0.6.0--0.5.0.sql
Normal file
5
client/cdb_dataservices_client--0.6.0--0.5.0.sql
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
--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_client UPDATE TO '0.5.0'" to load this file. \quit
|
||||||
|
DROP FUNCTION IF EXISTS cdb_dataservices_client._cdb_route_with_waypoints (text, text, geometry(Point, 4326)[], text, text[], text);
|
||||||
|
DROP FUNCTION IF EXISTS cdb_dataservices_client.cdb_route_with_waypoints (geometry(Point, 4326)[], text, text[], text);
|
1256
client/cdb_dataservices_client--0.6.0.sql
Normal file
1256
client/cdb_dataservices_client--0.6.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
comment = 'CartoDB dataservices client API extension'
|
comment = 'CartoDB dataservices client API extension'
|
||||||
default_version = '0.5.0'
|
default_version = '0.6.0'
|
||||||
requires = 'plproxy, cartodb'
|
requires = 'plproxy, cartodb'
|
||||||
superuser = true
|
superuser = true
|
||||||
schema = cdb_dataservices_client
|
schema = cdb_dataservices_client
|
||||||
|
@ -89,6 +89,15 @@
|
|||||||
- { name: options, type: "text[]", default: 'ARRAY[]::text[]' }
|
- { name: options, type: "text[]", default: 'ARRAY[]::text[]' }
|
||||||
- { name: units, type: "text", default: "'kilometers'"}
|
- { name: units, type: "text", default: "'kilometers'"}
|
||||||
|
|
||||||
|
- name: cdb_route_with_waypoints
|
||||||
|
return_type: cdb_dataservices_client.simple_route
|
||||||
|
multi_field: true
|
||||||
|
params:
|
||||||
|
- { name: waypoints, type: "geometry(Point, 4326)[]" }
|
||||||
|
- { name: mode, type: text }
|
||||||
|
- { name: options, type: "text[]", default: 'ARRAY[]::text[]' }
|
||||||
|
- { name: units, type: "text", default: "'kilometers'"}
|
||||||
|
|
||||||
- name: obs_get_demographic_snapshot
|
- name: obs_get_demographic_snapshot
|
||||||
return_type: json
|
return_type: json
|
||||||
params:
|
params:
|
||||||
|
@ -11,7 +11,17 @@ BEGIN
|
|||||||
RETURN ret;
|
RETURN ret;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE 'plpgsql';
|
$$ LANGUAGE 'plpgsql';
|
||||||
-- Exercise the public and the proxied function
|
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_client.simple_route AS $$
|
||||||
|
DECLARE
|
||||||
|
ret cdb_dataservices_client.simple_route;
|
||||||
|
BEGIN
|
||||||
|
RAISE NOTICE 'cdb_dataservices_server.cdb_route_with_waypoints invoked with params (%, %, %, %, %, %)', username, orgname, waypoints, mode, options, units;
|
||||||
|
SELECT NULL, 2.22, 500 INTO ret;
|
||||||
|
RETURN ret;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql';
|
||||||
|
-- Exercise the public and the proxied functions
|
||||||
SELECT cdb_route_point_to_point('POINT(-87.81406 41.89308)'::geometry,'POINT(-87.79209 41.86138)'::geometry, 'car');
|
SELECT cdb_route_point_to_point('POINT(-87.81406 41.89308)'::geometry,'POINT(-87.79209 41.86138)'::geometry, 'car');
|
||||||
NOTICE: cdb_dataservices_client._cdb_route_point_to_point(7): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.cdb_route_point_to_point invoked with params (test_user, <NULL>, 0101000000D53E1D8F19F455C0185B087250F24440, 0101000000465F419AB1F255C0D8B628B341EE4440, car, {}, kilometers)
|
NOTICE: cdb_dataservices_client._cdb_route_point_to_point(7): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.cdb_route_point_to_point invoked with params (test_user, <NULL>, 0101000000D53E1D8F19F455C0185B087250F24440, 0101000000465F419AB1F255C0D8B628B341EE4440, car, {}, kilometers)
|
||||||
CONTEXT: SQL statement "SELECT * FROM cdb_dataservices_client._cdb_route_point_to_point(username, orgname, origin, destination, mode, options, units)"
|
CONTEXT: SQL statement "SELECT * FROM cdb_dataservices_client._cdb_route_point_to_point(username, orgname, origin, destination, mode, options, units)"
|
||||||
@ -39,3 +49,30 @@ PL/pgSQL function cdb_route_point_to_point(geometry,geometry,text,text[],text) l
|
|||||||
(,5.33,100)
|
(,5.33,100)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cdb_route_with_waypoints(Array['POINT(-87.81406 41.89308)'::geometry,'POINT(-87.80406 41.87308)'::geometry,'POINT(-87.79209 41.86138)'::geometry], 'car');
|
||||||
|
NOTICE: cdb_dataservices_client._cdb_route_with_waypoints(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.cdb_route_with_waypoints invoked with params (test_user, <NULL>, {0101000000D53E1D8F19F455C0185B087250F24440:0101000000650113B875F355C05665DF15C1EF4440:0101000000465F419AB1F255C0D8B628B341EE4440}, car, {}, kilometers)
|
||||||
|
CONTEXT: SQL statement "SELECT * FROM cdb_dataservices_client._cdb_route_with_waypoints(username, orgname, waypoints, mode, options, units)"
|
||||||
|
PL/pgSQL function cdb_route_with_waypoints(geometry[],text,text[],text) line 16 at SQL statement
|
||||||
|
cdb_route_with_waypoints
|
||||||
|
--------------------------
|
||||||
|
(,2.22,500)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cdb_route_with_waypoints(Array['POINT(-87.81406 41.89308)'::geometry,'POINT(-87.80406 41.87308)'::geometry,'POINT(-87.79209 41.86138)'::geometry], 'car', ARRAY['mode_type=shortest']::text[]);
|
||||||
|
NOTICE: cdb_dataservices_client._cdb_route_with_waypoints(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.cdb_route_with_waypoints invoked with params (test_user, <NULL>, {0101000000D53E1D8F19F455C0185B087250F24440:0101000000650113B875F355C05665DF15C1EF4440:0101000000465F419AB1F255C0D8B628B341EE4440}, car, {mode_type=shortest}, kilometers)
|
||||||
|
CONTEXT: SQL statement "SELECT * FROM cdb_dataservices_client._cdb_route_with_waypoints(username, orgname, waypoints, mode, options, units)"
|
||||||
|
PL/pgSQL function cdb_route_with_waypoints(geometry[],text,text[],text) line 16 at SQL statement
|
||||||
|
cdb_route_with_waypoints
|
||||||
|
--------------------------
|
||||||
|
(,2.22,500)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cdb_route_with_waypoints(Array['POINT(-87.81406 41.89308)'::geometry,'POINT(-87.80406 41.87308)'::geometry,'POINT(-87.79209 41.86138)'::geometry], 'car', ARRAY[]::text[], 'miles');
|
||||||
|
NOTICE: cdb_dataservices_client._cdb_route_with_waypoints(6): [contrib_regression] REMOTE NOTICE: cdb_dataservices_server.cdb_route_with_waypoints invoked with params (test_user, <NULL>, {0101000000D53E1D8F19F455C0185B087250F24440:0101000000650113B875F355C05665DF15C1EF4440:0101000000465F419AB1F255C0D8B628B341EE4440}, car, {}, miles)
|
||||||
|
CONTEXT: SQL statement "SELECT * FROM cdb_dataservices_client._cdb_route_with_waypoints(username, orgname, waypoints, mode, options, units)"
|
||||||
|
PL/pgSQL function cdb_route_with_waypoints(geometry[],text,text[],text) line 16 at SQL statement
|
||||||
|
cdb_route_with_waypoints
|
||||||
|
--------------------------
|
||||||
|
(,2.22,500)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
@ -15,7 +15,24 @@ END;
|
|||||||
$$ LANGUAGE 'plpgsql';
|
$$ LANGUAGE 'plpgsql';
|
||||||
|
|
||||||
|
|
||||||
-- Exercise the public and the proxied function
|
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_client.simple_route AS $$
|
||||||
|
DECLARE
|
||||||
|
ret cdb_dataservices_client.simple_route;
|
||||||
|
BEGIN
|
||||||
|
RAISE NOTICE 'cdb_dataservices_server.cdb_route_with_waypoints invoked with params (%, %, %, %, %, %)', username, orgname, waypoints, mode, options, units;
|
||||||
|
SELECT NULL, 2.22, 500 INTO ret;
|
||||||
|
RETURN ret;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE 'plpgsql';
|
||||||
|
|
||||||
|
|
||||||
|
-- Exercise the public and the proxied functions
|
||||||
SELECT cdb_route_point_to_point('POINT(-87.81406 41.89308)'::geometry,'POINT(-87.79209 41.86138)'::geometry, 'car');
|
SELECT cdb_route_point_to_point('POINT(-87.81406 41.89308)'::geometry,'POINT(-87.79209 41.86138)'::geometry, 'car');
|
||||||
SELECT cdb_route_point_to_point('POINT(-87.81406 41.89308)'::geometry,'POINT(-87.79209 41.86138)'::geometry, 'car', ARRAY['mode_type=shortest']::text[]);
|
SELECT cdb_route_point_to_point('POINT(-87.81406 41.89308)'::geometry,'POINT(-87.79209 41.86138)'::geometry, 'car', ARRAY['mode_type=shortest']::text[]);
|
||||||
SELECT cdb_route_point_to_point('POINT(-87.81406 41.89308)'::geometry,'POINT(-87.79209 41.86138)'::geometry, 'car', ARRAY[]::text[], 'miles');
|
SELECT cdb_route_point_to_point('POINT(-87.81406 41.89308)'::geometry,'POINT(-87.79209 41.86138)'::geometry, 'car', ARRAY[]::text[], 'miles');
|
||||||
|
|
||||||
|
SELECT cdb_route_with_waypoints(Array['POINT(-87.81406 41.89308)'::geometry,'POINT(-87.80406 41.87308)'::geometry,'POINT(-87.79209 41.86138)'::geometry], 'car');
|
||||||
|
SELECT cdb_route_with_waypoints(Array['POINT(-87.81406 41.89308)'::geometry,'POINT(-87.80406 41.87308)'::geometry,'POINT(-87.79209 41.86138)'::geometry], 'car', ARRAY['mode_type=shortest']::text[]);
|
||||||
|
SELECT cdb_route_with_waypoints(Array['POINT(-87.81406 41.89308)'::geometry,'POINT(-87.80406 41.87308)'::geometry,'POINT(-87.79209 41.86138)'::geometry], 'car', ARRAY[]::text[], 'miles');
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
# Routing Functions
|
# Routing Functions
|
||||||
|
|
||||||
Routing is the navigation from a defined start location to a defined end location. The calculated results are displayed as turn-by-turn directions on your map, based on the transportation mode that you specified. Routing services through CartoDB are available by requesting a single function in the Data Services API.
|
Routing is the navigation from a defined start location to a defined end location. The calculated results are displayed as turn-by-turn directions on your map, based on the transportation mode that you specified. Routing services through CartoDB are available by using the available functions in the Data Services API.
|
||||||
|
|
||||||
### cdb_route_point_to_point(_origin geometry(Point), destination geometry(Point), mode text, [options text[], units text]_)
|
### cdb_route_point_to_point(_origin geometry(Point), destination geometry(Point), mode text, [options text[], units text]_)
|
||||||
|
|
||||||
|
Returns a route from origin to destination.
|
||||||
|
|
||||||
#### Arguments
|
#### Arguments
|
||||||
|
|
||||||
Name | Type | Description | Accepted values
|
Name | Type | Description | Accepted values
|
||||||
@ -36,6 +38,44 @@ INSERT INTO <TABLE> (duration, length, the_geom) SELECT duration, length, shape
|
|||||||
UPDATE <TABLE> SET the_geom = (SELECT shape FROM cdb_route_point_to_point('POINT(-3.70237112 40.41706163)'::geometry,'POINT(-3.69909883 40.41236875)'::geometry, 'car', ARRAY['mode_type=shortest']::text[]))
|
UPDATE <TABLE> SET the_geom = (SELECT shape FROM cdb_route_point_to_point('POINT(-3.70237112 40.41706163)'::geometry,'POINT(-3.69909883 40.41236875)'::geometry, 'car', ARRAY['mode_type=shortest']::text[]))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### cdb_route_with_waypoints(_waypoints geometry(Point)[], mode text, [options text[], units text]_)
|
||||||
|
|
||||||
|
Returns a route that goes from origin to destination and whose path travels through the defined locations.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
Name | Type | Description | Accepted values
|
||||||
|
--- | --- | --- | ---
|
||||||
|
`waypoints` | `geometry(Point)[]` | Array of ordered points, in 4326 projection, which defines the origin point, one or more locations for the route path to travel through, and the destination. The first element of the array defines the origin and the last element the destination of the route. |
|
||||||
|
`mode` | `text` | Type of transport used to calculate the isolines. | `car`, `walk`, `bicycle` or `public_transport`
|
||||||
|
`options` | `text[]` | (Optional) Multiple options to add more capabilities to the analysis. See [Optional routing parameters](#optional-routing-parameters) for details.
|
||||||
|
`units` | `text` | Unit used to represent the length of the route. | `kilometers`, `miles`. By default is `kilometers`
|
||||||
|
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
Name | Type | Description
|
||||||
|
--- | --- | ---
|
||||||
|
`duration` | `integer` | Duration in seconds of the calculated route.
|
||||||
|
`length` | `real` | Length in the defined unit in the `units` field. `kilometers` by default .
|
||||||
|
`the_geom` | `geometry(LineString)` | LineString geometry of the calculated route in the 4326 projection.
|
||||||
|
|
||||||
|
*Note*: A request to the function _cdb\_route\_with\_waypoints(waypoints geometry(Point)[], mode text, [options text[], units text])_ with only two points in the geometry array are automatically defined as origin and destination. It is equivalent to performing the following request with these two locations as parameters: _cdb\_route\_point\_to\_point(origin geometry(Point), destination geometry(Point), mode text, [options text[], units text])_.
|
||||||
|
|
||||||
|
#### Examples
|
||||||
|
|
||||||
|
##### Insert the values from the calculated route in your table
|
||||||
|
|
||||||
|
```bash
|
||||||
|
INSERT INTO <TABLE> (duration, length, the_geom) SELECT duration, length, shape FROM cdb_route_with_waypoints(Array['POINT(-3.7109 40.4234)'::GEOMETRY, 'POINT(-3.7059 40.4203)'::geometry, 'POINT(-3.7046 40.4180)'::geometry]::geometry[], 'walk')
|
||||||
|
```
|
||||||
|
##### Update the geometry field with the calculated route shape
|
||||||
|
|
||||||
|
```bash
|
||||||
|
UPDATE <TABLE> SET the_geom = (SELECT shape FROM cdb_route_with_waypoints(Array['POINT(-3.7109 40.4234)'::GEOMETRY, 'POINT(-3.7059 40.4203)'::geometry, 'POINT(-3.7046 40.4180)'::geometry]::geometry[], 'car', ARRAY['mode_type=shortest']::text[]))
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Optional routing parameters
|
### Optional routing parameters
|
||||||
|
|
||||||
The optional value parameters must be passed using the format: `option=value`.
|
The optional value parameters must be passed using the format: `option=value`.
|
||||||
|
@ -13,8 +13,8 @@ OLD_VERSIONS = $(wildcard old_versions/*.sql)
|
|||||||
# @see http://www.postgresql.org/docs/current/static/extend-pgxs.html
|
# @see http://www.postgresql.org/docs/current/static/extend-pgxs.html
|
||||||
DATA = $(NEW_EXTENSION_ARTIFACT) \
|
DATA = $(NEW_EXTENSION_ARTIFACT) \
|
||||||
$(OLD_VERSIONS) \
|
$(OLD_VERSIONS) \
|
||||||
cdb_dataservices_server--0.7.4--0.8.0.sql \
|
cdb_dataservices_server--0.8.0--0.9.0.sql \
|
||||||
cdb_dataservices_server--0.8.0--0.7.4.sql
|
cdb_dataservices_server--0.9.0--0.8.0.sql
|
||||||
|
|
||||||
REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql)))
|
REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql)))
|
||||||
TEST_DIR = test/
|
TEST_DIR = test/
|
||||||
|
102
server/extension/cdb_dataservices_server--0.8.0--0.9.0.sql
Normal file
102
server/extension/cdb_dataservices_server--0.8.0--0.9.0.sql
Normal file
@ -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;
|
||||||
|
|
||||||
|
|
86
server/extension/cdb_dataservices_server--0.9.0--0.8.0.sql
Normal file
86
server/extension/cdb_dataservices_server--0.9.0--0.8.0.sql
Normal file
@ -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;
|
2025
server/extension/cdb_dataservices_server--0.9.0.sql
Normal file
2025
server/extension/cdb_dataservices_server--0.9.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
comment = 'CartoDB dataservices server extension'
|
comment = 'CartoDB dataservices server extension'
|
||||||
default_version = '0.8.0'
|
default_version = '0.9.0'
|
||||||
requires = 'plpythonu, plproxy, postgis, cdb_geocoder'
|
requires = 'plpythonu, plproxy, postgis, cdb_geocoder'
|
||||||
superuser = true
|
superuser = true
|
||||||
schema = cdb_dataservices_server
|
schema = cdb_dataservices_server
|
||||||
|
@ -4,12 +4,10 @@ CREATE TYPE cdb_dataservices_server.simple_route AS (
|
|||||||
duration integer
|
duration integer
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_route_with_waypoints(
|
||||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_route_point_to_point(
|
|
||||||
username TEXT,
|
username TEXT,
|
||||||
orgname TEXT,
|
orgname TEXT,
|
||||||
origin geometry(Point, 4326),
|
waypoints geometry(Point, 4326)[],
|
||||||
destination geometry(Point, 4326),
|
|
||||||
mode TEXT,
|
mode TEXT,
|
||||||
options text[] DEFAULT ARRAY[]::text[],
|
options text[] DEFAULT ARRAY[]::text[],
|
||||||
units text DEFAULT 'kilometers')
|
units text DEFAULT 'kilometers')
|
||||||
@ -30,20 +28,18 @@ RETURNS cdb_dataservices_server.simple_route AS $$
|
|||||||
try:
|
try:
|
||||||
client = MapzenRouting(user_routing_config.mapzen_api_key)
|
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")
|
plpy.notice("Empty origin or destination")
|
||||||
quota_service.increment_empty_service_use()
|
quota_service.increment_empty_service_use()
|
||||||
return [None, None, None]
|
return [None, None, None]
|
||||||
|
|
||||||
orig_lat = plpy.execute("SELECT ST_Y('%s') AS lat" % origin)[0]['lat']
|
waypoint_coords = []
|
||||||
orig_lon = plpy.execute("SELECT ST_X('%s') AS lon" % origin)[0]['lon']
|
for waypoint in waypoints:
|
||||||
origin_coordinates = Coordinate(orig_lon, orig_lat)
|
lat = plpy.execute("SELECT ST_Y('%s') AS lat" % waypoint)[0]['lat']
|
||||||
dest_lat = plpy.execute("SELECT ST_Y('%s') AS lat" % destination)[0]['lat']
|
lon = plpy.execute("SELECT ST_X('%s') AS lon" % waypoint)[0]['lon']
|
||||||
dest_lon = plpy.execute("SELECT ST_X('%s') AS lon" % destination)[0]['lon']
|
waypoint_coords.append(Coordinate(lon,lat))
|
||||||
dest_coordinates = Coordinate(dest_lon, dest_lat)
|
|
||||||
|
|
||||||
resp = client.calculate_route_point_to_point(origin_coordinates, dest_coordinates, mode, options, units)
|
|
||||||
|
|
||||||
|
resp = client.calculate_route_point_to_point(waypoint_coords, mode, options, units)
|
||||||
if resp and resp.shape:
|
if resp and resp.shape:
|
||||||
shape_linestring = polyline_to_linestring(resp.shape)
|
shape_linestring = polyline_to_linestring(resp.shape)
|
||||||
if shape_linestring:
|
if shape_linestring:
|
||||||
|
38
server/extension/sql/105_route_between_points.sql
Normal file
38
server/extension/sql/105_route_between_points.sql
Normal file
@ -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)
|
||||||
|
|
@ -5,8 +5,11 @@ SELECT exists(SELECT *
|
|||||||
WHERE ns.nspname = 'cdb_dataservices_server'
|
WHERE ns.nspname = 'cdb_dataservices_server'
|
||||||
AND proname = 'cdb_route_point_to_point'
|
AND proname = 'cdb_route_point_to_point'
|
||||||
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, geometry, text, text[], text');
|
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
|
self._url = base_url
|
||||||
|
|
||||||
@qps_retry
|
@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):
|
options=[], units=METRICS_UNITS):
|
||||||
parsed_options = self.__parse_options(options)
|
parsed_options = self.__parse_options(options)
|
||||||
mode_param = self.__parse_mode_param(mode, parsed_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,
|
json_request_params = self.__parse_json_parameters(directions,
|
||||||
mode_param,
|
mode_param,
|
||||||
units)
|
units)
|
||||||
@ -67,11 +67,16 @@ class MapzenRouting:
|
|||||||
|
|
||||||
return json.dumps(json_options)
|
return json.dumps(json_options)
|
||||||
|
|
||||||
def __parse_directions(self, origin, destination):
|
def __parse_directions(self, waypoints):
|
||||||
return {"locations": [
|
path = []
|
||||||
{"lon": origin.longitude, "lat": origin.latitude},
|
for idx, point in enumerate(waypoints):
|
||||||
{"lon": destination.longitude, "lat": destination.latitude}
|
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):
|
def __parse_routing_response(self, response):
|
||||||
try:
|
try:
|
||||||
|
@ -10,7 +10,7 @@ from setuptools import setup, find_packages
|
|||||||
setup(
|
setup(
|
||||||
name='cartodb_services',
|
name='cartodb_services',
|
||||||
|
|
||||||
version='0.6.1',
|
version='0.6.2',
|
||||||
|
|
||||||
description='CartoDB Services API Python Library',
|
description='CartoDB Services API Python Library',
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@ requests_mock.Mocker.TEST_PREFIX = 'test_'
|
|||||||
@requests_mock.Mocker()
|
@requests_mock.Mocker()
|
||||||
class MapzenRoutingTestCase(unittest.TestCase):
|
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",
|
"id": "ethervoid-route",
|
||||||
"trip": {{
|
"trip": {{
|
||||||
"status": 0,
|
"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"}"""
|
MALFORMED_RESPONSE = """{"manolo": "escobar"}"""
|
||||||
|
|
||||||
@ -61,23 +104,39 @@ class MapzenRoutingTestCase(unittest.TestCase):
|
|||||||
|
|
||||||
def test_calculate_simple_routing_with_valid_params(self, req_mock):
|
def test_calculate_simple_routing_with_valid_params(self, req_mock):
|
||||||
req_mock.register_uri('GET', requests_mock.ANY,
|
req_mock.register_uri('GET', requests_mock.ANY,
|
||||||
text=self.GOOD_RESPONSE)
|
text=self.GOOD_RESPONSE_SIMPLE)
|
||||||
origin = Coordinate('-120.2', '38.5')
|
origin = Coordinate('-120.2', '38.5')
|
||||||
destination = Coordinate('-126.4', '43.2')
|
destination = Coordinate('-126.4', '43.2')
|
||||||
response = self.routing.calculate_route_point_to_point(origin,
|
waypoints = [origin, destination]
|
||||||
destination,
|
response = self.routing.calculate_route_point_to_point(waypoints,
|
||||||
'car')
|
'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.length, 444.59)
|
||||||
self.assertEqual(response.duration, 16969)
|
self.assertEqual(response.duration, 16969)
|
||||||
|
|
||||||
def test_uknown_mode_raise_exception(self, req_mock):
|
def test_uknown_mode_raise_exception(self, req_mock):
|
||||||
req_mock.register_uri('GET', requests_mock.ANY,
|
req_mock.register_uri('GET', requests_mock.ANY,
|
||||||
text=self.GOOD_RESPONSE)
|
text=self.GOOD_RESPONSE_SIMPLE)
|
||||||
origin = Coordinate('-120.2', '38.5')
|
origin = Coordinate('-120.2', '38.5')
|
||||||
destination = Coordinate('-126.4', '43.2')
|
destination = Coordinate('-126.4', '43.2')
|
||||||
|
waypoints = [origin, destination]
|
||||||
|
|
||||||
assert_raises(WrongParams,
|
assert_raises(WrongParams,
|
||||||
self.routing.calculate_route_point_to_point,
|
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)
|
||||||
|
@ -32,3 +32,24 @@ class TestRoutingFunctions(TestCase):
|
|||||||
IntegrationTestHelper.execute_query(self.sql_api_url, query)
|
IntegrationTestHelper.execute_query(self.sql_api_url, query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
assert_equal(e.message[0], "The api_key must be provided")
|
assert_equal(e.message[0], "The api_key must be provided")
|
||||||
|
|
||||||
|
def test_if_select_with_routing_with_waypoints_is_ok(self):
|
||||||
|
query = "SELECT duration, length, shape as the_geom " \
|
||||||
|
"FROM cdb_route_with_waypoints('Array['POINT(-3.7109 40.4234)'::GEOMETRY, "\
|
||||||
|
"'POINT(-3.7059 40.4203)'::geometry, 'POINT(-3.7046 40.4180)'::geometry]" \
|
||||||
|
"::geometry[], 'car', " \
|
||||||
|
"ARRAY['mode_type=shortest']::text[])&api_key={0}".format(
|
||||||
|
self.env_variables['api_key'])
|
||||||
|
routing = IntegrationTestHelper.execute_query(self.sql_api_url, query)
|
||||||
|
assert_not_equal(routing['the_geom'], None)
|
||||||
|
|
||||||
|
def test_if_select_with_routing_with_waypoints_without_api_key_raise_error(self):
|
||||||
|
query = "SELECT duration, length, shape as the_geom " \
|
||||||
|
"FROM cdb_route_with_waypoints('Array['POINT(-3.7109 40.4234)'::GEOMETRY, "\
|
||||||
|
"'POINT(-3.7059 40.4203)'::geometry, 'POINT(-3.7046 40.4180)'::geometry]" \
|
||||||
|
"::geometry[], 'car', " \
|
||||||
|
"ARRAY['mode_type=shortest']::text[])&api_key={0}"
|
||||||
|
try:
|
||||||
|
IntegrationTestHelper.execute_query(self.sql_api_url, query)
|
||||||
|
except Exception as e:
|
||||||
|
assert_equal(e.message[0], "The api_key must be provided")
|
||||||
|
Loading…
Reference in New Issue
Block a user