Compare commits

...

129 Commits

Author SHA1 Message Date
Mario de Frutos
587ae051f5 Fixed DO integration test fixture 2016-05-25 15:58:52 +02:00
Carla
b33d696817 Merge pull request #189 from CartoDB/development
Add routing_with_waypoints functions to Data Services API
2016-05-25 15:47:32 +02:00
Carla
5e027d5001 Merge pull request #188 from CartoDB/add_waypoints_doc
Add route_with_waypoints to documentation
2016-05-25 15:35:16 +02:00
Carla
337c47cd81 Update routing_functions.md 2016-05-25 15:19:08 +02:00
Carla
bf121ea3e3 add note about function equivalence with 2 points 2016-05-25 14:49:32 +02:00
Carla Iriberri
21aac960a6 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
2016-05-25 11:38:37 +02:00
Carla
ae86785ece fix function signature 2016-05-25 11:28:13 +02:00
Carla
7815c9cdc7 Update routing_functions.md 2016-05-24 18:04:15 +02:00
Carla
d17b5656fb Update test_helper.py 2016-05-24 13:19:16 +02:00
Carla
f46305de6f Update test_helper.py 2016-05-24 13:18:43 +02:00
Mario de Frutos
0fc1a24aec Added data observatory config 2016-05-23 15:35:35 +02:00
csobier
ed667dc301 Merge pull request #186 from CartoDB/master
edited geocoding code example
2016-05-20 13:56:58 -04:00
csobier
982f178d5a edited geocoding code example 2016-05-20 13:38:04 -04:00
csobier
3c222bd82d Merge pull request #185 from CartoDB/master
fixed spacing of heading after autogenerated table in the docs
2016-05-19 08:52:08 -04:00
csobier
bbcba337f5 fixed spacing of heading after autogenerated table in the docs 2016-05-19 08:40:04 -04:00
csobier
6887adcdb0 Merge pull request #184 from CartoDB/docs-fix-heading-spaces
fixed spacing after auto-generated table in order to show heading cor…
2016-05-19 08:35:34 -04:00
csobier
7b8165fbed fixed spacing after auto-generated table in order to show heading correctly in output 2016-05-19 08:30:46 -04:00
csobier
48779e56ef Merge pull request #165 from CartoDB/161-docs-obs-functions
adding placeholder for obs functions-WIP
2016-05-18 09:59:09 -04:00
Mario de Frutos
2a98a673d1 Merge pull request #182 from CartoDB/development
Quota management docs and integrations tests fixes
2016-05-18 15:21:36 +02:00
Mario de Frutos
9a49a20358 All integration tests working 2016-05-18 15:19:33 +02:00
Mario de Frutos
d63c688851 Merge pull request #181 from CartoDB/quota_management_doc
Document about how quota management works
2016-05-18 14:54:53 +02:00
csobier
0d5fa7a199 removed username from segmentation for consistency- this branch is ready to go 2016-05-17 19:58:07 -04:00
Andrew W. Hill
5e61ef2076 Update demographic_functions.md
removed username
2016-05-17 18:54:56 -04:00
csobier
75fc489143 applied Carla's edits 2016-05-17 15:01:56 -04:00
Mario de Frutos
3d617a4349 Fixed markdown syntax 2016-05-17 16:47:50 +02:00
Mario de Frutos
6abc5a4cdd Added section how the quota is spent in the document 2016-05-17 16:35:41 +02:00
Carla
fedcd606c5 add street level clarification for geocoding 2016-05-17 16:14:01 +02:00
Carla
4730088a22 Update quota_management.md 2016-05-17 16:11:58 +02:00
Carla
8df879f7d3 Add remaining credits left calculation tip 2016-05-17 16:09:09 +02:00
Carla
8a8a5e11b5 Update quota_management.md 2016-05-17 16:05:47 +02:00
Mario de Frutos
eb6fe79a4c Document about how quota management works 2016-05-17 15:55:57 +02:00
Stuart Lynn
182e6a0e92 update segmentation table 2016-05-17 09:38:29 -04:00
Mario de Frutos
77e31db729 Merge pull request #180 from CartoDB/development
More fixes for integration tests
2016-05-16 17:52:45 +02:00
Mario de Frutos
67383efd44 More fixes for integration tests 2016-05-16 17:51:25 +02:00
Mario de Frutos
0ac00153be Merge pull request #179 from CartoDB/development
More fixes for integration tests
2016-05-16 17:43:11 +02:00
Mario de Frutos
6052582a0c More fixes for integration tests 2016-05-16 17:41:44 +02:00
Mario de Frutos
31d3111b82 Merge pull request #178 from CartoDB/development
Fixed some integration tests result
2016-05-16 17:34:53 +02:00
Mario de Frutos
50c4126747 Fixed some integration tests result 2016-05-16 17:33:49 +02:00
csobier
5376af3d2b moved order of some examples for output 2016-05-16 08:48:51 -04:00
csobier
f9c0b73737 fixed some spelling errors and code examples, wordsmithed segmentation level descriptions 2016-05-16 08:33:38 -04:00
Mario de Frutos
0d90b602cb Merge pull request #177 from CartoDB/development
Hotifix: obs_general_quota logic missing in the redis config
2016-05-16 14:20:22 +02:00
Mario de Frutos
bb17b3bff7 Hotifix: obs_general_quota logic missing in the redis config 2016-05-16 14:19:08 +02:00
Mario de Frutos
aa3cb46dee Merge pull request #176 from CartoDB/development
Data observatory release v1
2016-05-16 11:06:18 +02:00
Mario de Frutos
86dabe1c35 Version file for server 0.8.0 2016-05-16 11:04:07 +02:00
Mario de Frutos
22883352e1 Version file for client 0.5.0 2016-05-16 11:03:57 +02:00
Mario de Frutos
6540519a91 Merge pull request #174 from CartoDB/observatory_release_v1
[don't merge yet] Observatory release v1
2016-05-16 10:58:21 +02:00
Mario de Frutos
5d6c3d7b11 Maintain old snapshot functions to avoid break compatibility 2016-05-16 10:25:27 +02:00
Mario de Frutos
8680c9cbd0 We let the old qlik snapshots functions but we make new ones with the new snapshot part from observatory' 2016-05-16 10:25:27 +02:00
Mario de Frutos
f59217779e New integration tests for data observatory functions 2016-05-16 10:25:27 +02:00
Mario de Frutos
c7c9e6e284 Server side new data observatory functions (v0.8.0) 2016-05-16 10:25:26 +02:00
Carla Iriberri
64d2afb536 Client side for the new data observatory functions (v0.5.0) 2016-05-16 10:25:26 +02:00
Stuart Lynn
632cfd9293 Proper segment names 2016-05-13 17:34:04 -04:00
Stuart Lynn
4f8fc16434 Updating documentation with categories and examples 2016-05-13 17:00:38 -04:00
Stuart Lynn
1039d1caa8 Update demographic_functions.md
Adding in example response and field details
2016-05-13 14:49:47 -04:00
andrewxhill
d745ba2ae7 first changes 2016-05-11 09:45:02 -04:00
Mario de Frutos
42a33cf74c Merge pull request #173 from CartoDB/development
On 4xx we have to return an empty response instead of an exception
2016-05-10 17:08:06 +02:00
Mario de Frutos
33b48ade5c Version 0.7.4 file 2016-05-10 17:00:42 +02:00
Mario de Frutos
efdc1b759e Merge pull request #172 from CartoDB/return_null_instead_of_crash_in_4xx
On 4xx we have to return an empty response instead of an exception
2016-05-10 16:58:49 +02:00
Mario de Frutos
3e09605757 On 4xx we have to return an empty response instead of an exception 2016-05-10 16:46:38 +02:00
Mario de Frutos
d49f97de2b Merge pull request #171 from CartoDB/development
Change loopback to observatory just to call the observatory extension functions
2016-05-10 10:10:03 +02:00
Mario de Frutos
bf2930984d Version 0.7.3 file 2016-05-09 18:32:12 +02:00
Mario de Frutos
1345a97055 Merge pull request #170 from CartoDB/change_green_blue_implementation
Change loopback to observatory just to call the observatory extension functions
2016-05-09 18:30:46 +02:00
Mario de Frutos
0735bbcb41 Change loopback to observatory just to call the observatory extension functions 2016-05-09 18:25:44 +02:00
csobier
8c6318e25d removed comments about function signature, changed code to appear correctly in output 2016-05-09 08:36:05 -04:00
Mario de Frutos
5de6a2430d Fix client downgrade script problem 2016-05-09 09:42:13 +02:00
csobier
d29b156d76 Merge pull request #164 from CartoDB/docs-797-best-practices
added best practices as an H3 under the Overview, data services api i…
2016-05-04 14:11:45 -04:00
Carla Iriberri
01a3fa3b59 Corrected error in insertinto statements 2016-05-04 20:06:37 +02:00
Carla Iriberri
9b88e91ec2 remove a select example 2016-05-04 20:01:37 +02:00
Carla Iriberri
fdc58f1eb0 Remove selects from geocoding functions 2016-05-04 20:00:04 +02:00
Carla Iriberri
5ea0d0e6da Remove comment related to admin0 geocoding 2016-05-04 19:54:11 +02:00
Carla Iriberri
a6de16449f Removing select statements 2016-05-04 19:52:22 +02:00
Mario de Frutos
693c7739fb Version 0.7.2 file 2016-05-04 16:53:11 +02:00
Mario de Frutos
bbea5518d3 Merge pull request #168 from CartoDB/obs_green_blue_deploy
Green/Blue deploy system for the observatory functions
2016-05-04 16:50:26 +02:00
Andrew W. Hill
df8810f55d Update demographic_functions.md 2016-05-03 14:36:05 -04:00
Mario de Frutos
e81dadaf2e Green/Blue deploy system for the observatory functions 2016-05-03 13:49:14 +02:00
csobier
7cb89434bc testing table output 2016-05-02 12:14:02 -04:00
csobier
7434b72a20 Fixed table spacing 2016-05-02 12:04:21 -04:00
csobier
6017944db1 added markdown table for demographic measures 2016-05-02 11:39:02 -04:00
csobier
2628a73a3f applied username for consitency, updated notes about availability-WIP 2016-05-02 10:25:59 -04:00
csobier
b6cf319ed5 added demo & segment docs from obs-ext source file 2016-05-02 09:15:48 -04:00
csobier
ee3913dd86 applied edits to overview based on Carlas review 2016-04-28 09:47:26 -04:00
Mario de Frutos
97b415080d Added data observatory config 2016-04-27 15:42:06 +02:00
Mario de Frutos
dcfa0ff5d8 Update configuration for server 2016-04-27 15:38:48 +02:00
csobier
ae109a8cdc edited overview and best practices section for clarity 2016-04-26 14:26:29 -04:00
csobier
e70794a620 added best practices as an H3 under the Overview, data services api integration section 2016-04-26 12:31:08 -04:00
csobier
9b48a4756b adding placeholder for obs functions-WIP 2016-04-25 13:25:27 -04:00
Mario de Frutos
ee13920a8e Server SQL file for version 0.7.1 2016-04-25 11:12:46 +02:00
Mario de Frutos
5efb81d809 Merge pull request #162 from CartoDB/data_observatory_quota_override
Use redis or db data observatory quota value
2016-04-25 11:12:01 +02:00
Mario de Frutos
4407ff630e Change data observatory config file to segragate more in order to prepare for future observatory elements 2016-04-25 10:03:39 +02:00
Mario de Frutos
a9c420ba7b Use redis or db data observatory quota value 2016-04-25 09:33:18 +02:00
csobier
976697c81e Merge pull request #127 from CartoDB/mapzen_geocoder_doc
[do NOT merge] Add mapzen geocoder as provider in the geocoding docs
2016-04-21 09:58:43 -04:00
csobier
3de15de1c9 Merge pull request #102 from CartoDB/routing_function_docs
[do NOT merge] Routing function docs
2016-04-21 09:58:21 -04:00
Mario de Frutos
303c7c81fb Merge pull request #160 from CartoDB/development
Check for snapshot instead of the_geom in the data observatory integr…
2016-04-21 12:32:23 +02:00
Mario de Frutos
b9757d2026 Check for snapshot instead of the_geom in the data observatory integration tests 2016-04-21 12:31:39 +02:00
Mario de Frutos
8aaaba3737 Merge pull request #159 from CartoDB/development
Add api_key parameter to data observatory integration tests
2016-04-21 12:15:36 +02:00
Mario de Frutos
e73d6b84ff Add api_key parameter to data observatory integration tests 2016-04-21 12:14:48 +02:00
Mario de Frutos
178651150c Merge pull request #158 from CartoDB/development
More fixes to data observatory integration tests
2016-04-21 12:11:30 +02:00
Mario de Frutos
b0d614d032 More fixes to data observatory integration tests 2016-04-21 12:10:35 +02:00
Mario de Frutos
b3e6d6731a Merge pull request #157 from CartoDB/development
Rename data observatory funtion call in the integration tests
2016-04-21 12:07:01 +02:00
Mario de Frutos
403f0d2164 Rename data observatory funtion call in the integration tests 2016-04-21 12:05:45 +02:00
csobier
4c5c31cfea removed null select example, woo 2016-04-18 09:19:05 -04:00
csobier
5ac9bd884f what about the SELECT examples for street? 2016-04-18 08:46:05 -04:00
csobier
6b6c30ff17 merged master, ready to roll 2016-04-15 13:50:37 -04:00
csobier
3ed89c09d5 clarified actual behavior of geocoding descriptions 2016-04-15 13:41:24 -04:00
Mario de Frutos
2ffee03e7b Merge branch 'master' into mapzen_geocoder_doc 2016-04-15 16:49:08 +02:00
csobier
9fce6b558b applied update for DataServices API issue#145 2016-04-15 07:29:53 -04:00
csobier
6eb8df2955 removed typo from copypaste review, and added more descriptions for geocoding functions 2016-04-13 13:28:42 -04:00
csobier
1fbab0617f change point to geometries 2016-04-13 12:32:00 -04:00
csobier
d18eb95575 clarified equalness in isolines 2016-04-13 12:21:38 -04:00
Sergio Álvarez Leiva
3c1250ee72 Update overview.md 2016-04-13 13:16:24 +02:00
Sergio Álvarez Leiva
7e8d666c8c Update geocoding_functions.md 2016-04-13 13:14:25 +02:00
csobier
f223ad9ca0 fixing indentation 2016-04-12 19:54:13 -04:00
csobier
2c8cfa3032 hyperlink fix 2016-04-12 19:50:30 -04:00
csobier
0b53ede06c applied some formatting changes 2016-04-12 19:41:34 -04:00
csobier
6bd854a395 added more geocoding funtion descriptions 2016-04-12 19:15:51 -04:00
csobier
30cb5869f1 reorg of docs format and editing, removed mentions of providers 2016-04-12 17:19:51 -04:00
csobier
187fe8f849 updated routing functions description 2016-04-12 14:35:05 -04:00
csobier
ee9e5aba38 updated renamed link 2016-04-11 10:21:45 -04:00
csobier
6105f677af added mapzen basemap details 2016-04-11 10:20:43 -04:00
csobier
9e90ee3e1f clarified how to access Mapzen features 2016-04-11 09:01:49 -04:00
csobier
ea24aa938f added link in overview to quickstart rregarding mapzen setup 2016-04-11 08:21:26 -04:00
csobier
75d58dc836 fix url 2016-04-06 07:57:51 -04:00
csobier
652bd6abd6 fixed url 2016-04-06 07:56:15 -04:00
csobier
dab46269d4 url fixes 2016-04-06 07:42:38 -04:00
csobier
8eeef94eab added quick start info about mapzen 2016-04-05 16:21:34 -04:00
csobier
14d02fd63f added link to mapzen routing 2016-04-05 15:48:57 -04:00
csobier
28b4b12ce4 minor edits to mapzen geocoder provider inserts 2016-03-28 11:00:21 -04:00
Mario de Frutos
dd2af74b03 Add mapzen geocoder as provider in the geocoding docs 2016-03-28 16:47:22 +02:00
Mario de Frutos
30001b68a7 Routing functions docs 2016-03-17 20:05:49 +01:00
80 changed files with 16796 additions and 386 deletions

View File

@@ -30,6 +30,14 @@ Steps to deploy a new Data Services API version :
cd data-services/geocoder/extension
sudo make install
```
- install observatory extension
```
git clone git@github.com:CartoDB/observatory-extension.git
cd observatory
sudo make install
```
- install server and client extensions
@@ -49,6 +57,7 @@ Steps to deploy a new Data Services API version :
```
create extension cdb_geocoder;
create extension plproxy;
create extension observatory;
create extension cdb_dataservices_server;
create extension cdb_dataservices_client;
```
@@ -65,10 +74,11 @@ Steps to deploy a new Data Services API version :
SELECT CDB_Conf_SetConf('redis_metadata_config', '{"redis_host": "localhost", "redis_port": 26379, "sentinel_master_id": "", "timeout": 0.1, "redis_db": 5}');
SELECT CDB_Conf_SetConf('redis_metrics_config', '{"redis_host": "localhost", "redis_port": 6379, "sentinel_master_id": "", "timeout": 0.1, "redis_db": 5}');
SELECT CDB_Conf_SetConf('heremaps_conf', '{"app_id": "APP_ID", "app_code": "APP_CODE", "geocoder_cost_per_hit": "COST_PER_HIT"}');
SELECT CDB_Conf_SetConf('heremaps_conf', '{"geocoder": {"app_id": "here_geocoder_app_id", "app_code": "here_geocoder_app_code", "geocoder_cost_per_hit": "1"}, "isolines" : {"app_id": "here_isolines_app_id", "app_code": "here_geocoder_app_code"}}');
SELECT CDB_Conf_SetConf('user_config', '{"is_organization": false, "entity_name": "<YOUR_USERNAME>"}')
SELECT CDB_Conf_SetConf('mapzen_conf', '{"routing_app_key": "ROUTING_API_KEY", "geocoder_app_key": "GEOCODER_API_KEY"}');
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('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)

View File

@@ -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_client--0.3.0--0.4.0.sql \
cdb_dataservices_client--0.4.0--0.3.0.sql
cdb_dataservices_client--0.5.0--0.6.0.sql \
cdb_dataservices_client--0.6.0--0.5.0.sql
REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql)))

View 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;

View 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);

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
comment = 'CartoDB dataservices client API extension'
default_version = '0.4.0'
default_version = '0.6.0'
requires = 'plproxy, cartodb'
superuser = true
schema = cdb_dataservices_client

View File

@@ -1,7 +1,7 @@
--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.3.0'" to load this file. \quit
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_demographic_snapshot (text, text, geometry(Geometry, 4326), text, text)
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_segment_snapshot (text, text, geometry(Geometry, 4326), text)
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_get_demographic_snapshot (geometry(Geometry, 4326), text, text)
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_get_segment_snapshot (geometry(Geometry, 4326), text)
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_demographic_snapshot (text, text, geometry(Geometry, 4326), text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_segment_snapshot (text, text, geometry(Geometry, 4326), text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_get_demographic_snapshot (geometry(Geometry, 4326), text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_get_segment_snapshot (geometry(Geometry, 4326), text);

View File

@@ -0,0 +1,597 @@
--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
--
-- 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.obs_getdemographicsnapshot (geom geometry(Geometry, 4326), time_span text DEFAULT NULL, geometry_level text DEFAULT NULL)
RETURNS SETOF JSON AS $$
DECLARE
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;
RETURN QUERY
SELECT * FROM cdb_dataservices_client._obs_getdemographicsnapshot(username, orgname, geom, time_span, geometry_level);
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getsegmentsnapshot (geom geometry(Geometry, 4326), geometry_level text DEFAULT NULL)
RETURNS SETOF JSON AS $$
DECLARE
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;
RETURN QUERY
SELECT * FROM cdb_dataservices_client._obs_getsegmentsnapshot(username, orgname, geom, geometry_level);
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getboundary (geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL)
RETURNS Geometry AS $$
DECLARE
ret Geometry;
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 cdb_dataservices_client._obs_getboundary(username, orgname, geom, boundary_id, time_span) INTO ret;
RETURN ret;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getboundaryid (geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL)
RETURNS text AS $$
DECLARE
ret text;
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 cdb_dataservices_client._obs_getboundaryid(username, orgname, geom, boundary_id, time_span) INTO ret;
RETURN ret;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getboundarybyid (geometry_id text, boundary_id text, time_span text DEFAULT NULL)
RETURNS Geometry AS $$
DECLARE
ret Geometry;
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 cdb_dataservices_client._obs_getboundarybyid(username, orgname, geometry_id, boundary_id, time_span) INTO ret;
RETURN ret;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getboundariesbygeometry (geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
DECLARE
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;
RETURN QUERY
SELECT * FROM cdb_dataservices_client._obs_getboundariesbygeometry(username, orgname, geom, boundary_id, time_span, overlap_type) AS query;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getboundariesbypointandradius (geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
DECLARE
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;
RETURN QUERY
SELECT * FROM cdb_dataservices_client._obs_getboundariesbypointandradius(username, orgname, geom, radius, boundary_id, time_span, overlap_type) AS query;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getpointsbygeometry (geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
DECLARE
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;
RETURN QUERY
SELECT * FROM cdb_dataservices_client._obs_getpointsbygeometry(username, orgname, geom, boundary_id, time_span, overlap_type) AS query;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getpointsbypointandradius (geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
DECLARE
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;
RETURN QUERY
SELECT * FROM cdb_dataservices_client._obs_getpointsbypointandradius(username, orgname, geom, radius, boundary_id, time_span, overlap_type) AS query;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getmeasure (geom Geometry, measure_id text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL)
RETURNS numeric AS $$
DECLARE
ret numeric;
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 cdb_dataservices_client._obs_getmeasure(username, orgname, geom, measure_id, normalize, boundary_id, time_span) INTO ret;
RETURN ret;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getcategory (geom Geometry, category_id text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL)
RETURNS text AS $$
DECLARE
ret text;
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 cdb_dataservices_client._obs_getcategory(username, orgname, geom, category_id, boundary_id, time_span) INTO ret;
RETURN ret;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getuscensusmeasure (geom Geometry, name text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL)
RETURNS numeric AS $$
DECLARE
ret numeric;
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 cdb_dataservices_client._obs_getuscensusmeasure(username, orgname, geom, name, normalize, boundary_id, time_span) INTO ret;
RETURN ret;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getuscensuscategory (geom Geometry, name text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL)
RETURNS text AS $$
DECLARE
ret text;
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 cdb_dataservices_client._obs_getuscensuscategory(username, orgname, geom, name, boundary_id, time_span) INTO ret;
RETURN ret;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getpopulation (geom Geometry, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL)
RETURNS numeric AS $$
DECLARE
ret numeric;
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 cdb_dataservices_client._obs_getpopulation(username, orgname, geom, normalize, boundary_id, time_span) INTO ret;
RETURN ret;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_search (search_term text, relevant_boundary text DEFAULT NULL)
RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$
DECLARE
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;
RETURN QUERY
SELECT * FROM cdb_dataservices_client._obs_search(username, orgname, search_term, relevant_boundary) AS query;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
--
-- 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.obs_getavailableboundaries (geom Geometry, timespan text DEFAULT NULL)
RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$
DECLARE
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;
RETURN QUERY
SELECT * FROM cdb_dataservices_client._obs_getavailableboundaries(username, orgname, geom, timespan) AS query;
END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getdemographicsnapshot (username text, organization_name text, geom geometry(Geometry, 4326), time_span text DEFAULT NULL, geometry_level text DEFAULT NULL)
RETURNS SETOF JSON AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT cdb_dataservices_server.obs_getdemographicsnapshot (username, organization_name, geom, time_span, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getsegmentsnapshot (username text, organization_name text, geom geometry(Geometry, 4326), geometry_level text DEFAULT NULL)
RETURNS SETOF JSON AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT cdb_dataservices_server.obs_getsegmentsnapshot (username, organization_name, geom, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundary (username text, organization_name text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL)
RETURNS Geometry AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT cdb_dataservices_server.obs_getboundary (username, organization_name, geom, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundaryid (username text, organization_name text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL)
RETURNS text AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT cdb_dataservices_server.obs_getboundaryid (username, organization_name, geom, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundarybyid (username text, organization_name text, geometry_id text, boundary_id text, time_span text DEFAULT NULL)
RETURNS Geometry AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT cdb_dataservices_server.obs_getboundarybyid (username, organization_name, geometry_id, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundariesbygeometry (username text, organization_name text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT * FROM cdb_dataservices_server.obs_getboundariesbygeometry (username, organization_name, geom, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getboundariesbypointandradius (username text, organization_name text, geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT * FROM cdb_dataservices_server.obs_getboundariesbypointandradius (username, organization_name, geom, radius, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpointsbygeometry (username text, organization_name text, geom geometry(Geometry, 4326), boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT * FROM cdb_dataservices_server.obs_getpointsbygeometry (username, organization_name, geom, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpointsbypointandradius (username text, organization_name text, geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text DEFAULT NULL, overlap_type text DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT * FROM cdb_dataservices_server.obs_getpointsbypointandradius (username, organization_name, geom, radius, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getmeasure (username text, organization_name text, geom Geometry, measure_id text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL)
RETURNS numeric AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT cdb_dataservices_server.obs_getmeasure (username, organization_name, geom, measure_id, normalize, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getcategory (username text, organization_name text, geom Geometry, category_id text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL)
RETURNS text AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT cdb_dataservices_server.obs_getcategory (username, organization_name, geom, category_id, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getuscensusmeasure (username text, organization_name text, geom Geometry, name text, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL)
RETURNS numeric AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT cdb_dataservices_server.obs_getuscensusmeasure (username, organization_name, geom, name, normalize, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getuscensuscategory (username text, organization_name text, geom Geometry, name text, boundary_id text DEFAULT NULL, time_span text DEFAULT NULL)
RETURNS text AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT cdb_dataservices_server.obs_getuscensuscategory (username, organization_name, geom, name, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getpopulation (username text, organization_name text, geom Geometry, normalize text DEFAULT 'area', boundary_id text DEFAULT NULL, time_span text DEFAULT NULL)
RETURNS numeric AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT cdb_dataservices_server.obs_getpopulation (username, organization_name, geom, normalize, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_search (username text, organization_name text, search_term text, relevant_boundary text DEFAULT NULL)
RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT * FROM cdb_dataservices_server.obs_search (username, organization_name, search_term, relevant_boundary);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_client._obs_getavailableboundaries (username text, organization_name text, geom Geometry, time_span text DEFAULT NULL)
RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$
CONNECT cdb_dataservices_client._server_conn_str();
SELECT * FROM cdb_dataservices_server.obs_getavailableboundaries (username, organization_name, geom, time_span);
$$ LANGUAGE plproxy;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getdemographicsnapshot(geom geometry(Geometry, 4326), time_span text, geometry_level text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getsegmentsnapshot(geom geometry(Geometry, 4326), geometry_level text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundary(geom geometry(Geometry, 4326), boundary_id text, time_span text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundaryid(geom geometry(Geometry, 4326), boundary_id text, time_span text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundarybyid(geometry_id text, boundary_id text, time_span text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundariesbygeometry(geom geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getboundariesbypointandradius(geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text, overlap_type text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpointsbygeometry(geom geometry(Geometry, 4326), boundary_id text, time_span text, overlap_type text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpointsbypointandradius(geom geometry(Geometry, 4326), radius numeric, boundary_id text, time_span text, overlap_type text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getmeasure(geom Geometry, measure_id text, normalize text, boundary_id text, time_span text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getcategory(geom Geometry, category_id text, boundary_id text, time_span text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getuscensusmeasure(geom Geometry, name text, normalize text, boundary_id text, time_span text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getuscensuscategory(geom Geometry, name text, boundary_id text, time_span text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getpopulation(geom Geometry, normalize text, boundary_id text, time_span text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_search(search_term text, relevant_boundary text) TO publicuser;
GRANT EXECUTE ON FUNCTION cdb_dataservices_client.obs_getavailableboundaries(geom Geometry, time_span text) TO publicuser;

View File

@@ -0,0 +1,40 @@
--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.4.0'" to load this file. \quit
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_demographic_snapshot(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_get_segment_snapshot(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getdemographicsnapshot(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getsegmentsnapshot(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundary(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundaryid(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundarybyid(text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundariesbygeometry(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getboundariesbypointandradius(geometry, numeric, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpointsbygeometry(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpointsbypointandradius(geometry, numeric, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getmeasure(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getcategory(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getuscensusmeasure(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getuscensuscategory(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getpopulation(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_search(text);
DROP FUNCTION IF EXISTS cdb_dataservices_client._obs_getavailableboundaries(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_get_demographic_snapshot(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_get_segment_snapshot(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getdemographicsnapshot(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getsegmentsnapshot(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundary(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundaryid(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundarybyid(text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundariesbygeometry(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getboundariesbypointandradius(geometry, numeric, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getpointsbygeometry(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getpointsbypointandradius(geometry, numeric, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getmeasure(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getcategory(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getuscensusmeasure(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getuscensuscategory(geometry, text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getpopulation(geometry);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_search(text);
DROP FUNCTION IF EXISTS cdb_dataservices_client.obs_getavailableboundaries(geometry);

File diff suppressed because it is too large Load Diff

View File

@@ -89,6 +89,15 @@
- { name: options, type: "text[]", default: 'ARRAY[]::text[]' }
- { 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
return_type: json
params:
@@ -100,4 +109,163 @@
return_type: json
params:
- { name: geom, type: "geometry(Geometry, 4326)" }
- { name: geometry_level, type: text, default: "'\"us.census.tiger\".census_tract'::text" }
- { name: geometry_level, type: text, default: "'\"us.census.tiger\".census_tract'::text" }
- name: obs_getdemographicsnapshot
return_type: SETOF JSON
multi_row: true
params:
- { name: geom, type: "geometry(Geometry, 4326)" }
- { name: time_span, type: "text", default: 'NULL' }
- { name: geometry_level, type: text, default: 'NULL' }
- name: obs_getsegmentsnapshot
return_type: SETOF JSON
multi_row: true
params:
- { name: geom, type: "geometry(Geometry, 4326)" }
- { name: geometry_level, type: text, default: 'NULL' }
- name: obs_getboundary
return_type: Geometry
params:
- { name: geom, type: "geometry(Geometry, 4326)" }
- { name: boundary_id, type: text }
- { name: time_span, type: text, default: 'NULL'}
- name: obs_getboundaryid
return_type: text
params:
- { name: geom, type: "geometry(Geometry, 4326)" }
- { name: boundary_id, type: text }
- { name: time_span, type: text, default: 'NULL'}
- name: obs_getboundarybyid
return_type: Geometry
params:
- { name: geometry_id, type: text }
- { name: boundary_id, type: text }
- { name: time_span, type: text, default: 'NULL'}
- name: obs_getboundariesbygeometry
return_type: TABLE(the_geom geometry, geom_refs text)
multi_row: true
multi_field: true
table_fields:
- { name: the_geom, type: geometry }
- { name: geom_refs, type: text }
params:
- { name: geom, type: "geometry(Geometry, 4326)" }
- { name: boundary_id, type: text }
- { name: time_span, type: text, default: 'NULL'}
- { name: overlap_type, type: text, default: "'intersects'"}
- name: obs_getboundariesbypointandradius
return_type: TABLE(the_geom geometry, geom_refs text)
multi_row: true
multi_field: true
table_fields:
- { name: the_geom, type: geometry }
- { name: geom_refs, type: text }
params:
- { name: geom, type: "geometry(Geometry, 4326)" }
- { name: radius, type: numeric }
- { name: boundary_id, type: text }
- { name: time_span, type: text, default: 'NULL'}
- { name: overlap_type, type: text, default: "'intersects'"}
- name: obs_getpointsbygeometry
return_type: TABLE(the_geom geometry, geom_refs text)
multi_row: true
multi_field: true
table_fields:
- { name: the_geom, type: geometry }
- { name: geom_refs, type: text }
params:
- { name: geom, type: "geometry(Geometry, 4326)" }
- { name: boundary_id, type: text }
- { name: time_span, type: text, default: 'NULL'}
- { name: overlap_type, type: text, default: "'intersects'"}
- name: obs_getpointsbypointandradius
return_type: TABLE(the_geom geometry, geom_refs text)
multi_row: true
multi_field: true
table_fields:
- { name: the_geom, type: geometry }
- { name: geom_refs, type: text }
params:
- { name: geom, type: "geometry(Geometry, 4326)" }
- { name: radius, type: numeric }
- { name: boundary_id, type: text }
- { name: time_span, type: text, default: 'NULL'}
- { name: overlap_type, type: text, default: "'intersects'"}
- name: obs_getmeasure
return_type: numeric
params:
- { name: geom, type: Geometry }
- { name: measure_id, type: text }
- { name: normalize, type: text, default: "'area'"}
- { name: boundary_id, type: text, default: 'NULL' }
- { name: time_span, type: text, default: 'NULL'}
- name: obs_getcategory
return_type: text
params:
- { name: geom, type: Geometry }
- { name: category_id, type: text }
- { name: boundary_id, type: text, default: 'NULL' }
- { name: time_span, type: text, default: 'NULL'}
- name: obs_getuscensusmeasure
return_type: numeric
params:
- { name: geom, type: Geometry }
- { name: name, type: text }
- { name: normalize, type: text, default: "'area'"}
- { name: boundary_id, type: text, default: 'NULL' }
- { name: time_span, type: text, default: 'NULL'}
- name: obs_getuscensuscategory
return_type: text
params:
- { name: geom, type: Geometry }
- { name: name, type: text }
- { name: boundary_id, type: text, default: 'NULL' }
- { name: time_span, type: text, default: 'NULL'}
- name: obs_getpopulation
return_type: numeric
params:
- { name: geom, type: Geometry }
- { name: normalize, type: text, default: "'area'"}
- { name: boundary_id, type: text, default: 'NULL' }
- { name: time_span, type: text, default: 'NULL'}
- name: obs_search
return_type: TABLE(id text, description text, name text, aggregate text, source text)
multi_row: true
multi_field: true
table_fields:
- { name: id, type: text }
- { name: description, type: text }
- { name: name, type: text }
- { name: aggregate, type: text }
- { name: source, type: text }
params:
- { name: search_term, type: text }
- { name: relevant_boundary, type: text, default: 'NULL' }
- name: obs_getavailableboundaries
return_type: TABLE(boundary_id text, description text, time_span text, tablename text)
multi_row: true
multi_field: true
table_fields:
- { name: boundary_id, type: text }
- { name: description, type: text }
- { name: time_span, type: text }
- { name: tablename, type: text }
params:
- { name: geom, type: Geometry }
- { name: timespan, type: text, default: 'NULL'}

View File

@@ -11,7 +11,17 @@ BEGIN
RETURN ret;
END;
$$ 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');
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)"
@@ -39,3 +49,30 @@ PL/pgSQL function cdb_route_point_to_point(geometry,geometry,text,text[],text) l
(,5.33,100)
(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)

File diff suppressed because one or more lines are too long

View File

@@ -15,7 +15,24 @@ END;
$$ 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', 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_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');

File diff suppressed because one or more lines are too long

View File

@@ -2,14 +2,12 @@
The CartoDB Data Services API offers a set of location based services that can be used programatically to empower your geospatial applications.
The geocoder functions allow you to match your data with geometries on your map. This geocoding service can be used programatically to geocode datasets via the CartoDB SQL API. It is fed from _Open Data_ and it serves geometries for countries, provinces, states, cities, postal codes, IP addresses and street addresses.
The isoline functions provide a way to generate isolines in terms of distance and time, by means of the available isodistance and isochrone functions useful for Trade Areas Analysis.
## Documentation
* [Quickstart](quickstart.md)
* [General Concepts](general_concepts.md)
* [Overview](overview.md)
* [Geocoding Functions](geocoding_functions.md)
* [Isoline Functions](isoline_functions.md)
* [Quota Information](quota_information.md)
* [Routing Functions](routing_functions.md)
* [Demographic Functions](demographic_functions.md)
* [Segmentation Functions](segmentation_functions.md)
* [Quota Information](quota_information.md)

View File

@@ -0,0 +1,155 @@
# Demographic Functions
The Demographic Snapshot enables you to collect demographic reports around a point location. For example, you can take the coordinates of a coffee shop and find the average population characteristics, such as total population, educational attainment, housing and income information around that location. You can use raw street addresses by combining the Demographic Snapshot with CartoDB's geocoding features. If you need help creating coordinates from addresses, see the [Geocoding Functions](/cartodb-platform/dataservices-api/geocoding-functions/) documentation.
_**Note:** The Demographic Snapshot functions are only available for the United States._
## OBS_GetDemographicSnapshot( point geometry )
Fields returned include information about income, education, transportation, race, and more. Not all fields will have information for every coordinate queried.
### Arguments
Name | Description | Example Values
--- | --- | ---
point geometry | A point geometry. You can use the helper function, `CDB_LatLng` to quickly generate one from latitude and longitude | `CDB_LatLng(40.760410,-73.964242)`
### Returns
The Demographic Snapshot contains a broad subset of demographic measures in the Data Observatory. Over 80 measurements are returned by a single API request. For each demographic measure, the API returns the following values.
Value | Name | Tablename | Aggregate | Type | Description
----- | ---- | --------- | --------- | ---- |------------
The value of the measure at the point you requested | The name of the measure | The table it was drawn from | Indicated if the measure is a count or median. | postgresql | A description of the measure
For example the "Female Population" measure returns
```json
obs_getdemographicsnapshot: {
"value": 32.5395066379175,
"name": "Female Population",
"tablename": "obs_1a098da56badf5f32e336002b0a81708c40d29cd",
"aggregate": "sum",
"type": "Numeric",
"description": "The number of people within each geography who are female."
}
```
**For details, see the [Glossary of Demographic Measures](#glossary-of-demographic-measures).**
### Examples
```bash
https://{username}.cartodb.com/api/v2/sql?q=SELECT * FROM
OBS_GetDemographicSnapshot({{point geometry}})
```
##### Get the Geographic Snapshot of a Demographic
__Get the Demographic Snapshot at Camp David__
```bash
https://{username}.cartodb.com/api/v2/sql?q=SELECT * FROM
OBS_GetDemographicSnapshot(CDB_LatLng(39.648333, -77.465))
```
__Get the Demographic Snapshot in the Upper West Side__
```bash
https://{username}.cartodb.com/api/v2/sql?q=SELECT * FROM
OBS_GetDemographicSnapshot(CDB_LatLng(40.80, -73.960))
```
## Glossary of Demographic Measures
This list contains the demographic measures and response names for results from the ```OBS_GetDemographicSnapshot``` function.
Measure name | Measure Description | Response Mame | Response Units
--- | --- | --- | ---
Total Population | The total number of all people living in a given geographic area. This is a very useful catch-all denominator when calculating rates. | total_pop | Count per sq. km
Male Population | The number of people within each geography who are male. | male_pop | Count per sq. km
Female Population | The number of people within each geography who are female.| female_pop | Count per sq. km
Population not Hispanic | The number of people not identifying as Hispanic or Latino in each geography. | not_hispanic_pop | Count per sq. km
White Population | The number of people identifying as white, non-Hispanic in each geography. | white_pop | Count per sq. km
Black or African American Population| The number of people identifying as black or African American, non-Hispanic in each geography. | black_pop | Count per sq. km
American Indian and Alaska Native Population | The number of people identifying as American Indian or Alaska native in each geography.| amerindian_pop| Count per sq. km
Asian Population | The number of people identifying as Asian, non-Hispanic in each geography.| asian_pop | Count per sq. km
Other Race population | The number of people identifying as another race in each geography. | other_race_pop | Count per sq. km
Two or more races population| The number of people identifying as two or more races in each geography | two_or_more_races_pop | Count per sq. km
Hispanic Population | The number of people identifying as Hispanic or Latino in each geography. | hispanic_pop | Count per sq. km
Not a U.S. Citizen Population | The number of people within each geography who indicated that they are not U.S. citizens. | not_us_citizen_pop | Count per sq. km
Median Age | The median age of all people in a given geographic area.| median_age | Years
Children under 18 Years of Age | The number of people within each geography who are under 18 years of age.| children | Count per sq. km
Population 15 Years and Over | The number of people in a geographic area who are over the age of 15. This is used mostly as a denominator of marital status. | pop_15_and_over | Count per sq. km
Population 3 Years and Over | The total number of people in each geography age 3 years and over. This denominator is mostly used to calculate rates of school enrollment. | population_3_years_over | Count per sq. km
Population 5 Years and Over | The number of people in a geographic area who are over the age of 5. This is primarily used as a denominator of measures of language spoken at home.| pop_5_years_over | Count per sq. km
Workers over the Age of 16 | The number of people in each geography who work. Workers include those employed at private for-profit companies, the self-employed, government workers and non-profit employees. | workers_16_and_over | Count per sq. km
Workers age 16 and over who do not work from home| The number of workers over the age of 16 who do not work from home in a geographic area| commuters_16_over | Count per sq. km
Commuters by Car, Truck, or Van | The number of workers age 16 years and over within a geographic area who primarily traveled to work by car, truck or van. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. | commuters_by_car_truck_van | Count per sq. km
Commuters who drove alone | The number of workers age 16 years and over within a geographic area who primarily traveled by car driving alone. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. | commuters_drove_alone | Count per sq. km
Commuters by Carpool| The number of workers age 16 years and over within a geographic area who primarily traveled to work by carpool. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. | commuters_by_carpool | Count per sq. km
Commuters by Public Transportation | The number of workers age 16 years and over within a geographic area who primarily traveled to work by public transportation. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. | commuters_by_public_transportation | Count per sq. km |
Commuters by Bus | The number of workers age 16 years and over within a geographic area who primarily traveled to work by bus. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. This is a subset of workers who commuted by public transport. | commuters_by_bus| Count per sq. km
Commuters by Subway or Elevated | The number of workers age 16 years and over within a geographic area who primarily traveled to work by subway or elevated train. This is the principal mode of travel or type of conveyance, by distance rather than time, that the worker usually used to get from home to work. This is a subset of workers who commuted by public transport. | commuters_by_subway_or_elevated | Count per sq. km
Walked to Work | The number of workers age 16 years and over within a geographic area who primarily walked to work. This would mean that of any way of getting to work, they travelled the most distance walking. | walked_to_work | Count per sq. km
Worked at Home | The count within a geographical area of workers over the age of 16 who worked at home. | worked_at_home | Count per sq. km
Number of workers with less than 10 minute commute | The number of workers over the age of 16 who do not work from home and commute in less than 10 minutes in a geographic area. | commute_less_10_mins | Count per sq. km
Number of workers with a commute between 10 and 14 minutes| The number of workers over the age of 16 who do not work from home and commute in between 10 and 14 minutes in a geographic area. | commute_10_14_mins | Count per sq. km
Number of workers with a commute between 15 and 19 minutes | The number of workers over the age of 16 who do not work from home and commute in between 15 and 19 minutes in a geographic area. | commute_15_19_mins | Count per sq. km
Number of workers with a commute between 20 and 24 minutes | The number of workers over the age of 16 who do not work from home and commute in between 20 and 24 minutes in a geographic area. | commute_20_24_mins | Count per sq. km
Number of workers with a commute between 25 and 29 minutes | The number of workers over the age of 16 who do not work from home and commute in between 25 and 29 minutes in a geographic area. | commute_25_29_mins| Count per sq. km
Number of workers with a commute between 30 and 34 minutes | The number of workers over the age of 16 who do not work from home and commute in between 30 and 34 minutes in a geographic area. | commute_30_34_mins | Count per sq. km
Number of workers with a commute between 35 and 44 minutes | The number of workers over the age of 16 who do not work from home and commute in between 35 and 44 minutes in a geographic area. | commute_35_44_mins | Count per sq. km
Number of workers with a commute between 45 and 59 minutes | The number of workers over the age of 16 who do not work from home and commute in between 45 and 59 minutes in a geographic area. | commute_45_59_mins | Count per sq. km
Number of workers with a commute of over 60 minutes | The number of workers over the age of 16 who do not work from home and commute in over 60 minutes in a geographic area.| commute_60_more_mins | Count per sq. km
Aggregate travel time to work | The total number of minutes every worker over the age of 16 who did not work from home spent spent commuting to work in one day in a geographic area. | aggregate_travel_time_to_work | Minutes
Households | A count of the number of households in each geography. A household consists of one or more people who live in the same dwelling and also share at meals or living accommodation, and may consist of a single family or some other grouping of people. | households | Count per sq. km
Never Married | The number of people in a geographic area who have never been married. | pop_never_married | Count per sq. km
Currently married| The number of people in a geographic area who are currently married. | pop_now_married | Count per sq. km
Married but separated | The number of people in a geographic area who are married but separated.| pop_separated | Count per sq. km
Widowed | The number of people in a geographic area who are widowed.| pop_widowed | Count per sq. km
Divorced | The number of people in a geographic area who are divorced. | pop_divorced | Count per sq. km
Students Enrolled in School | The total number of people in each geography currently enrolled at any level of school, from nursery or pre-school to advanced post-graduate education. Only includes those over the age of 3. | in_school | Count per sq. km
Students Enrolled in Grades 1 to 4 | The total number of people in each geography currently enrolled in grades 1 through 4 inclusive. This corresponds roughly to elementary school. | in_grades_1_to_4 | Count per sq. km
Students Enrolled in Grades 5 to 8 | The total number of people in each geography currently enrolled in grades 5 through 8 inclusive. This corresponds roughly to middle school. | in_grades_5_to_8 | Count per sq. km
Students Enrolled in Grades 9 to 12 | The total number of people in each geography currently enrolled in grades 9 through 12 inclusive. This corresponds roughly to high school. | in_grades_9_to_12 | Count per sq. km
Students Enrolled as Undergraduate in College | The number of people in a geographic area who are enrolled in college at the undergraduate level. Enrollment refers to being registered or listed as a student in an educational program leading to a college degree. This may be a public school or college, a private school or college. | in_undergrad_college | Count per sq. km
Population 25 Years and Over | The number of people in a geographic area who are over the age of 25. This is used mostly as a denominator of educational attainment. | pop_25_years_over | Count per sq. km
Population Completed High School | The number of people in a geographic area over the age of 25 who completed high school, and did not complete a more advanced degree. | high_school_diploma| Count per sq. km
Population completed less than one year of college, no degree | The number of people in a geographic area over the age of 25 who attended college for less than one year and no further. | less_one_year_college | Count per sq. km
Population completed more than one year of college, no degree | The number of people in a geographic area over the age of 25 who attended college for more than one year but did not obtain a degree. | one_year_more_college | Count per sq. km
Population Completed Associate's Degree | The number of people in a geographic area over the age of 25 who obtained a associate's degree, and did not complete a more advanced degree.| associates_degree | Count per sq. km
Population Completed Bachelor's Degree| The number of people in a geographic area over the age of 25 who obtained a bachelor's degree, and did not complete a more advanced degree. | bachelors_degree| Count per sq. km
Population Completed Master's Degree | The number of people in a geographic area over the age of 25 who obtained a master's degree, but did not complete a more advanced degree. | masters_degree | Count per sq. km
Speaks only English at Home | The number of people in a geographic area over age 5 who speak only English at home. | speak_only_english_at_home | Count per sq. km
Speaks Spanish at Home | The number of people in a geographic area over age 5 who speak Spanish at home, possibly in addition to other languages. | speak_spanish_at_home | Count per sq. km
Population for Whom Poverty Status Determined | The number of people in each geography who could be identified as either living in poverty or not. This should be used as the denominator when calculating poverty rates, as it excludes people for whom it was not possible to determine poverty. | pop_determined_poverty_status | Count per sq. km
Income In The Past 12 Months Below Poverty Level | The number of people in a geographic area who are part of a family (which could be just them as an individual) determined to be "in poverty" following the [Office of Management and Budget's Directive 14](https://www.census.gov/hhes/povmeas/methodology/ombdir14.html). | poverty | Count per sq. km
Households with income less than $10,000 | The number of households in a geographic area whose annual income was less than $10,000. | income_less_10000 | Count per sq. km
Households with income of $10,000 to $14,999 | The number of households in a geographic area whose annual income was between $10,000 and $14,999. | income_10000_14999 | Count per sq. km
Households with income of $15,000 to $19,999 | The number of households in a geographic area whose annual income was between $15,000 and $19,999. | income_15000_19999 | Count per sq. km
Households with income of $20,000 To $24,999 | The number of households in a geographic area whose annual income was between $20,000 and $24,999. | income_20000_24999 | Count per sq. km
Households with income of $25,000 To $29,999 | The number of households in a geographic area whose annual income was between $20,000 and $24,999. | income_25000_29999 | Count per sq. km
Households with income of $30,000 To $34,999 | The number of households in a geographic area whose annual income was between $30,000 and $34,999. | income_30000_34999 | Count per sq. km
Households with income of $35,000 To $39,999 | The number of households in a geographic area whose annual income was between $35,000 and $39,999. | income_35000_39999 | Count per sq. km
Households with income of $40,000 To $44,999 | The number of households in a geographic area whose annual income was between $40,000 and $44,999. | income_40000_44999| Count per sq. km
Households with income of $45,000 To $49,999 | The number of households in a geographic area whose annual income was between $45,000 and $49,999. | income_45000_49999 | Count per sq. km
Households with income of $50,000 To $59,999 | The number of households in a geographic area whose annual income was between $50,000 and $59,999. | income_50000_59999 | Count per sq. km
Households with income of $60,000 To $74,999 | The number of households in a geographic area whose annual income was between $60,000 and $74,999. | income_60000_74999 | Count per sq. km
Households with income of $75,000 To $99,999 | The number of households in a geographic area whose annual income was between $75,000 and $99,999. | income_75000_99999 | Count per sq. km
Households with income of $100,000 To $124,999 | The number of households in a geographic area whose annual income was between $100,000 and $124,999. | income_100000_124999 | Count per sq. km
Households with income of $125,000 To $149,999 | The number of households in a geographic area whose annual income was between $125,000 and $149,999. | income_125000_149999 | Count per sq. km
Households with income of $150,000 To $199,999 | The number of households in a geographic area whose annual income was between $150,000 and $1999,999. | income_150000_199999 | Count per sq. km
Households with income of $200,000 Or More | The number of households in a geographic area whose annual income was more than $200,000. | income_200000_or_more | Count per sq. km
Median Household Income in the past 12 Months | Within a geographic area, the median income received by every household on a regular basis before payments for personal income taxes, social security, union dues, medicare deductions, etc. It includes income received from wages, salary, commissions, bonuses, and tips; self-employment income from own nonfarm or farm businesses, including proprietorships and partnerships; interest, dividends, net rental income, royalty income, or income from estates and trusts; Social Security or Railroad Retirement income; Supplemental Security Income (SSI); any cash public assistance or welfare payments from the state or local welfare office; retirement, survivor, or disability benefits; and any other sources of income received regularly such as Veterans' (VA) payments, unemployment and/or worker's compensation, child support, and alimony. | median_income | USD
Per Capita Income in the past 12 Months | | income_per_capita | USD
Gini Index | A measurement of the income distribution of a country's residents. | gini_index | None
Housing Units | A count of housing units in each geography. A housing unit is a house, an apartment, a mobile home or trailer, a group of rooms, or a single room occupied as separate living quarters, or if vacant, intended for occupancy as separate living quarters. | housing_units | Count per sq. km
Vacant Housing Units | The count of vacant housing units in a geographic area. A housing unit is vacant if no one is living in it at the time of enumeration, unless its occupants are only temporarily absent. Units temporarily occupied at the time of enumeration entirely by people who have a usual residence elsewhere are also classified as vacant. | vacant_housing_units | Count per sq. km
Vacant Housing Units for Rent | The count of vacant housing units in a geographic area that are for rent. A housing unit is vacant if no one is living in it at the time of enumeration, unless its occupants are only temporarily absent. Units temporarily occupied at the time of enumeration entirely by people who have a usual residence elsewhere are also classified as vacant. | vacant_housing_units_for_rent | Count per sq. km
Vacant Housing Units for Sale| The count of vacant housing units in a geographic area that are for sale. A housing unit is vacant if no one is living in it at the time of enumeration, unless its occupants are only temporarily absent. Units temporarily occupied at the time of enumeration entirely by people who have a usual residence elsewhere are also classified as vacant. | vacant_housing_units_for_sale | Count per sq. km
Owner-occupied Housing Units | The count of owner occupied housing units in a geographic area. | owner_occupied_housing_units | Count per sq. km
Owner-occupied Housing Units valued at $1,000,000 or more. | The count of owner occupied housing units in a geographic area that are valued at $1,000,000 or more. Value is the respondent's estimate of how much the property (house and lot, mobile home and lot, or condominium unit) would sell for if it were for sale. | million_dollar_housing_units | Count per sq. km
Owner-occupied Housing Units with a Mortgage | The count of housing units within a geographic area that are mortagaged. "Mortgage" refers to all forms of debt where the property is pledged as security for repayment of the debt, including deeds of trust, trust deed, contracts to purchase, land contracts, junior mortgages, and home equity loans. | mortgaged_housing_units | Count per sq. km
Median Rent | The median contract rent within a geographic area. The contract rent is the monthly rent agreed to or contracted for, regardless of any furnishings, utilities, fees, meals, or services that may be included. For vacant units, it is the monthly rent asked for the rental unit at the time of interview.| median_rent | USD
Percent of Household Income Spent on Rent | Within a geographic area, the median percentage of household income which was spent on gross rent. Gross rent is the amount of the contract rent plus the estimated average monthly cost of utilities (electricity, gas, water, sewer etc.) and fuels (oil, coal, wood, etc.) if these are paid by the renter. Household income is the sum of the income of all people 15 years and older living in the household. | percent_income_spent_on_rent | Percent

View File

@@ -1,33 +0,0 @@
# General Concepts
The Data Services API offers geocoding and isoline services on top of the CartoDB SQL API by means of a set of functions. Each one of these functions is oriented to one kind of operation and returns the corresponding geometry (a `polygon` or a `point`), according to the input information.
The Data Services API decouples the geocoding and isoline services from the CartoDB Editor. The API allows you to geocode data (from single rows, complete datasets, or simple inputs) and to perform trade areas analysis (computing isodistances or isochrones) programatically through authenticated requests.
The geometries provided by this API are projected in the projection [WGS 84 SRID 4326](http://spatialreference.org/ref/epsg/wgs-84/).
The Geocoder functions can return different types of geometries (points or polygons) as result of different geocoding processes. The CartoDB platform does not support multigeometry layers or datasets, therefore the final users of this Data Services API must check that they are using consistent geometry types inside a table to avoid further conflicts in the map visualization.
## Authentication
All requests performed to the CartoDB Data Services API must be authenticated with the user API Key. For more information about where to find your API Key, and how to authenticate your SQL API requests, view the [SQL API authentication](/cartodb-platform/sql-api/authentication/) guide.
## Errors
Errors are described in the response of the request. An example is as follows:
```json
{
error: [
"The api_key must be provided"
]
}
```
Since the Data Services API is used on top of the CartoDB SQL API, you can refer to the [Making calls to the SQL API](/cartodb-platform/sql-api/making-calls/) documentation for help debugging your SQL errors.
If the requested information is not in the CartoDB geocoding database, or if CartoDB is unable to recognize your input and match it with a result, the geocoding function returns `null` as a result.
## Limits
Usage of the Data Services API is subject to the CartoDB SQL API limits, stated in our [Terms of Service](https://cartodb.com/terms/#excessive).

View File

@@ -1,14 +1,38 @@
# Geocoding Functions
The [geocoder](https://cartodb.com/data/geocoder-api/) functions allow you to match your data with geometries on your map. This geocoding service can be used programatically to geocode datasets via the CartoDB SQL API. It is fed from _Open Data_ and it serves geometries for countries, provinces, states, cities, postal codes, IP addresses and street addresses. CartoDB provides functions for several different categories of geocoding through the Data Services API.
_**This service is subject to quota limitations and extra fees may apply**. View the [Quota Information](http://docs.cartodb.com/cartodb-platform/dataservices-api/quota-information/) section for details and recommendations about to quota consumption._
Here is an example of how to geocode a single country:
```bash
https://{username}.cartodb.com/api/v2/sql?q=SELECT cdb_geocode_admin0_polygon('USA')&api_key={api_key}
```
In order to geocode an existent CartoDB dataset, an SQL UPDATE statement must be used to populate the geometry column in the dataset with the results of the Data Services API. For example, if the column where you are storing the country names for each one of our rows is called `country_column`, run the following statement in order to geocode the dataset:
```bash
https://{username}.cartodb.com/api/v2/sql?q=UPDATE {tablename} SET the_geom = cdb_geocode_admin0_polygon('USA')&api_key={api_key}
```
Notice that you can make use of Postgres or PostGIS functions in your Data Services API requests, as the result is a geometry that can be handled by the system. For example, suppose you need to retrieve the centroid of a specific country, you can wrap the resulting geometry from the geocoder functions inside the PostGIS `ST_Centroid` function:
```bash
https://{username}.cartodb.com/api/v2/sql?q=UPDATE {tablename} SET the_geom = ST_Centroid(cdb_geocode_admin0_polygon('USA'))&api_key={api_key}
```
The following geocoding functions are available, grouped by categories.
## Country Geocoder
## Country geocoder
This function provides a country geocoding service. It recognizes the names of the different countries from different synonyms, such as their English name, their endonym, or their ISO2 or ISO3 codes.
This function geocodes your data into country border geometries. It recognizes the names of the different countries either by different synonyms (such as their English name or their endonym), or by ISO (ISO2 or ISO3) codes.
### cdb_geocode_admin0_polygon(_country_name text_)
Geocodes the text name of a country into a country_name geometry, displayed as polygon data.
#### Arguments
Name | Type | Description
@@ -21,25 +45,26 @@ Geometry (polygon, EPSG 4326) or null
#### Example
##### Select
```bash
SELECT cdb_geocode_admin0_polygon('France')
```
##### Update
##### Update the geometry of a table to geocode it
```bash
UPDATE {tablename} SET the_geom = cdb_geocode_admin0_polygon({country_column})
```
##### Insert a geocoded row into a table
## Level-1 Administrative regions geocoder
```bash
INSERT INTO {tablename} (the_geom) SELECT cdb_geocode_admin0_polygon('France')
```
The following functions provide a geocoding service for administrative regions of level 1 (or NUTS-1) such as states for the United States, *départements* in France or autonomous communities in Spain.
## Level-1 Administrative Regions Geocoder
This function geocodes your data into polygon geometries for [Level 1](https://en.wikipedia.org/wiki/Table_of_administrative_divisions_by_country), or [NUTS-1](https://en.wikipedia.org/wiki/NUTS_1_statistical_regions_of_England), administrative divisions (or units) of countries. For example, a "state" in the United States, "départements" in France, or an autonomous community in Spain.
### cdb_geocode_admin1_polygon(_admin1_name text_)
Geocodes the name of the province/state into a Level-1 administrative region, displayed as a polygon geometry.
#### Arguments
Name | Type | Description
@@ -52,20 +77,23 @@ Geometry (polygon, EPSG 4326) or null
#### Example
##### Select
```bash
SELECT cdb_geocode_admin1_polygon('Alicante')
```
##### Update
##### Update the geometry of a table to geocode it
```bash
UPDATE {tablename} SET the_geom = cdb_geocode_admin1_polygon({province_column})
```
##### Insert a geocoded row into a table
```bash
INSERT INTO {tablename} (the_geom) SELECT cdb_geocode_admin1_polygon('Alicante')
```
### cdb_geocode_admin1_polygon(_admin1_name text, country_name text_)
Geocodes the name of the province/state for a specified country into a Level-1 administrative region, displayed as a polygon geometry.
#### Arguments
Name | Type | Description
@@ -79,25 +107,26 @@ Geometry (polygon, EPSG 4326) or null
#### Example
##### Select
```bash
SELECT cdb_geocode_admin1_polygon('Alicante', 'Spain')
```
##### Update
##### Update the geometry of a table to geocode it
```bash
UPDATE {tablename} SET the_geom = cdb_geocode_admin1_polygon({province_column}, {country_column})
```
##### Insert a geocoded row into a table
```bash
INSERT INTO {tablename} (the_geom) SELECT cdb_geocode_admin1_polygon('Alicante', 'Spain')
```
## City geocoder
## City Geocoder
The following functions provide a city geocoder service. It is recommended to use the more specific geocoding function -- the one that requires more parameters — in order for the result to be as accurate as possible when several cities share their name. If there are duplicate results for a city name, the city name with the highest population will be returned.
This function geocodes your data into point geometries for names of cities. It is recommended to use geocoding functions that require more defined parameters — this returns more accurate results when several cities have the same name. _If there are duplicate results for a city name, the city name with the highest population will be returned._
### cdb_geocode_namedplace_point(_city_name text_)
Geocodes the text name of a city into a named place geometry, displayed as point data.
#### Arguments
Name | Type | Description
@@ -112,18 +141,23 @@ Geometry (point, EPSG 4326) or null
##### Select
```bash
SELECT cdb_geocode_namedplace_point('Barcelona')
```
##### Update
##### Update the geometry of a table to geocode it
```bash
UPDATE {tablename} SET the_geom = cdb_geocode_namedplace_point({city_column})
```
##### Insert a geocoded row into a table
```bash
INSERT INTO {tablename} (the_geom) SELECT cdb_geocode_namedplace_point('Barcelona')
```
### cdb_geocode_namedplace_point(_city_name text, country_name text_)
Geocodes the text name of a city for a specified country into a named place point geometry.
#### Arguments
Name | Type | Description
@@ -137,20 +171,22 @@ Geometry (point, EPSG 4326) or null
#### Example
##### Select
```bash
SELECT cdb_geocode_namedplace_point('Barcelona', 'Spain')
```
##### Update
##### Update the geometry of a table to geocode it
```bash
UPDATE {tablename} SET the_geom = cdb_geocode_namedplace_point({city_column}, 'Spain')
```
##### Insert a geocoded row into a table
```bash
INSERT INTO {tablename} (the_geom) SELECT cdb_geocode_namedplace_point('Barcelona', 'Spain')
```
### cdb_geocode_namedplace_point(_city_name text, admin1_name text, country_name text_)
Geocodes your data into a named place point geometry, containing the text name of a city, for a specified province/state and country. This is recommended for the most accurate geocoding of city data.
#### Arguments
Name | Type | Description
@@ -165,26 +201,28 @@ Geometry (point, EPSG 4326) or null
#### Example
##### Select
```bash
SELECT cdb_geocode_namedplace_point('New York', 'New York', 'USA')
```
##### Update
##### Update the geometry of a table to geocode it
```bash
UPDATE {tablename} SET the_geom = cdb_geocode_namedplace_point({city_column}, {province_column}, 'USA')
```
## Postal codes geocoder
##### Insert a geocoded row into a table
The following functions provide a postal code geocoding service that can be used to obtain points or polygon results. The postal code polygon geocoder covers the United States, France, Australia and Canada; a request for a different country will return an empty response.
```bash
INSERT INTO {tablename} (the_geom) SELECT cdb_geocode_namedplace_point('New York', 'New York', 'USA')
```
## Postal Code Geocoder
This function geocodes your data into point, or polygon, geometries for postal codes. The postal code polygon geocoder covers the United States, France, Australia and Canada; a request for a different country will return an empty response.
**Note:** For the USA, US Census [Zip Code Tabulation Areas](https://www.census.gov/geo/reference/zctas.html) (ZCTA) are used to reference geocodes for USPS postal codes service areas. See the [FAQs](http://docs.cartodb.com/faqs/datasets-and-data/#why-does-cartodb-use-census-bureau-zctas-and-not-usps-zip-codes-for-postal-codes) about datasets and data for details.
### cdb_geocode_postalcode_polygon(_postal_code text, country_name text_)
Goecodes the postal code for a specified country into a **polygon** geometry.
#### Arguments
Name | Type | Description
@@ -198,20 +236,22 @@ Geometry (polygon, EPSG 4326) or null
#### Example
##### Select
```bash
SELECT cdb_geocode_postalcode_polygon('11211', 'USA')
```
##### Update
##### Update the geometry of a table to geocode it
```bash
UPDATE {tablename} SET the_geom = cdb_geocode_postalcode_polygon({postal_code_column}, 'USA')
```
##### Insert a geocoded row into a table
```bash
INSERT INTO {tablename} (the_geom) SELECT cdb_geocode_postalcode_polygon('11211', 'USA')
```
### cdb_geocode_postalcode_point(_code text, country_name text_)
Goecodes the postal code for a specified country into a **point** geometry.
#### Arguments
Name | Type | Description
@@ -225,24 +265,27 @@ Geometry (point, EPSG 4326) or null
#### Example
##### Select
```bash
SELECT cdb_geocode_postalcode_point('11211', 'USA')
```
##### Update
##### Update the geometry of a table to geocode it
```bash
UPDATE {tablename} SET the_geom = cdb_geocode_postalcode_point({postal_code_column}, 'USA')
```
## IP addresses geocoder
##### Insert a geocoded row into a table
This function provides an IP address geocoding service, for both IPv4 and IPv6 addresses.
```bash
INSERT INTO {tablename} (the_geom) SELECT cdb_geocode_postalcode_point('11211', 'USA')
```
## IP Addresses Geocoder
This function geocodes your data into point geometries for IP addresses. This is useful if you are analyzing location based data, based on a set of user's IP addresses.
### cdb_geocode_ipaddress_point(_ip_address text_)
Geocodes a postal code from a specified country into an IP address, displayed as a point geometry.
#### Arguments
Name | Type | Description
@@ -256,33 +299,36 @@ Geometry (point, EPSG 4326) or null
#### Example
##### Select
```bash
SELECT cdb_geocode_ipaddress_point('102.23.34.1')
```
##### Update
##### Update the geometry of a table to geocode it
```bash
UPDATE {tablename} SET the_geom = cdb_geocode_ipaddress_point('102.23.34.1')
```
## Street-level geocoder
This function provides a street-level geocoding service. This service uses the street level geocoder defined for the user.
##### Insert a geocoded row into a table
**This service is subject to quota limitations, and extra fees may apply**. Please view our [terms and conditions](https://cartodb.com/terms/) and check out the [Quota information section](http://docs.cartodb.com/cartodb-platform/dataservices-api/quota-information/) for details and recommendations related with quota usage.
```bash
INSERT INTO {tablename} (the_geom) SELECT cdb_geocode_ipaddress_point('102.23.34.1')
```
## Street-Level Geocoder
This function geocodes your data into a point geometry for a street address. CartoDB uses several different service providers for street-level geocoding, depending on your platform. If you access CartoDB on a Google Cloud Platform, [Google Maps geocoding](https://developers.google.com/maps/documentation/geocoding/intro) is applied. All other platform users are provided with [HERE geocoding services](https://developer.here.com/rest-apis/documentation/geocoder/topics/quick-start.html). Additional service providers will be implemented in the future.
**This service is subject to quota limitations, and extra fees may apply**. View the [Quota information](http://docs.cartodb.com/cartodb-platform/dataservices-api/quota-information/) for details and recommendations about quota consumption.
### cdb_geocode_street_point(_search_text text, [city text], [state text], [country text]_)
Geocodes a complete address into a single street geometry, displayed as point data.
#### Arguments
Name | Type | Description
--- | --- | ---
`searchtext` | `text` | searchtext contains free-form text containing address elements. You can specify the searchtext parameter by itself, or you can specify it with other parameters to narrow your search. For example, you can specify the state or country parameters, along with a free-form address in the searchtext field.
`city` | `text` | (Optional) Name of the city
`state` | `text` | (Optional) Name of the state
`country` | `text` | (Optional) Name of the country
--- | --- | --- | ---
`searchtext` | `text` | searchtext contains free-form text containing address elements. You can specify the searchtext parameter by itself, or with other parameters, to narrow your search. For example, you can specify the state or country parameters, along with a free-form address in the searchtext field.
`city` | `text` | (Optional) Name of the city.
`state` | `text` | (Optional) Name of the state.
`country` | `text` | (Optional) Name of the country.
#### Returns
@@ -290,17 +336,14 @@ Geometry (point, EPSG 4326) or null
#### Example
##### Select
```bash
SELECT cdb_geocode_street_point('651 Lombard Street, San Francisco, California, United States')
SELECT cdb_geocode_street_point('651 Lombard Street', 'San Francisco')
SELECT cdb_geocode_street_point('651 Lombard Street', 'San Francisco', 'California')
SELECT cdb_geocode_street_point('651 Lombard Street', 'San Francisco', 'California', 'United States')
```
##### Update
##### Update the geometry of a table to geocode it
```bash
UPDATE {tablename} SET the_geom = cdb_geocode_street_point({street_name_column})
```
##### Insert a geocoded row into a table
```bash
INSERT INTO {tablename} (the_geom) SELECT cdb_geocode_street_point('651 Lombard Street', 'San Francisco', 'California', 'United States')
```

View File

@@ -0,0 +1,66 @@
All the services from Dataservices API are subject to quota management: check, limit, etc.
There are three main fields in the quota management:
- **Quota**: Number of requests of this kind the user could make, eg. Number of street geocoding requests
- **Soft limit**: This flag enables the user to surpass their assigned quota. When this flag is activated, there is no quota check so the user could make all the requests that they want. Consequently, the `hard_limit` flag, when enabled, indicates that the user cannot surpass the assigned quota.
- **Block price**: Price for every 1000 requests
All the user/organization quota information is stored in the user metadata in Redis but managed by the CartoDB Rails app through the User/Organization models. Nevertheless you could change/read the Redis information through the following keys:
- `hgetall rails:users:username`
- `hgetall rails:orgs:orgname`
This whole information is managed by the CartoDB Rails App too so we could make a numer of useful operations in order to know how much quota do you have, how much quota have you spent this month and so on.
###How can I know the current quota, number of uses, etc for a user?###
You could use the following endpoint to know it: https://<username>.cartodb.com/api/v1/users/<user_id>?api_key=<api_key>
In the result of this endpoint you can see blocks with all the information. Eg:
```
"geocoding": {
"quota": 1000,
"block_price": 1500,
"monthly_use": 743,
"hard_limit": true
}
```
### How can I set a new quota for a user###
This operation could be done through the rails console:
- First you have to connect to the rails console: `bundle exec rails c`
- Once in the console you have to get the target user/organization:
- `u = User.find(username: '<username>')`
- `o = Organization.find(name: '<orgname>')`
- After we have the user/organization, we could change the quota or the hard limit flag for the desired service. I'm going to use geocoding as an example but it could be done with all the services:
```
u.geocoding_quota = 2000
[u.soft_geocoding_limit = true|false]
u.save
```
```
o.geocoding_quota = 2000
o.save
```
- This way the user now has 2000 requests as their current quota
- We can only change the hard limit flag for users, not for organizations
### What services we could change?###
The following list numbers all the current services but this is a living list so it could keep growing in the future:
- Geocoding (street level): `geocoding_quota`, `soft_geocoding_limit`
- Isolines: `here_isolines_quota`, `soft_here_isolines_limit`
- Data observatory snapshot: `obs_snapshot_quota`, `soft_obs_snapshot_limit`
- Data observatory general: `obs_general_quota`, `soft_obs_general_limit`
### How is the quota spent?###
Almost in all the services: geocoding, data observatory snapshot and general the number of spent credits is calculated per request made (either successful or empty request).
In the case of the isolines service, the number of credits is calculated based on the number of isolines generated by the request. Ie. If your query generates 3 isolines for the request, you've spent 3 isolines credits.

View File

@@ -1,10 +1,20 @@
# Isoline Functions
The following functions provide an isolines generator service based on time or distance. This service uses the isolines service defined for the user (currently, only the [HERE](https://developer.here.com/coverage-info) isolines service is available).
[Isolines](https://cartodb.com/data/isolines/) are contoured lines that display equally calculated levels over a given surface area. This enables you to view polygon dimensions by forward or reverse measurements. Isoline functions are calculated as the intersection of areas from the origin point, measured by distance (isodistance) or time (isochrone). For example, the distance of a road from a sidewalk. Isoline services through CartoDB are available by requesting a single function in the Data Services API.
**This service is subject to quota limitations, and extra fees may apply**. Please view our [terms and conditions](https://cartodb.com/terms/) and check out the [Quota information section](http://docs.cartodb.com/cartodb-platform/dataservices-api/quota-information/) for details and recommendations related with quota usage.
_**This service is subject to quota limitations and extra fees may apply**. View the [Quota Information](http://docs.cartodb.com/cartodb-platform/dataservices-api/quota-information/) section for details and recommendations about to quota consumption._
### cdb_isodistance(_source geometry, mode text, range integer[], [options text[]]_)
You can use the isoline functions to retrieve, for example, isochrone lines from a certain location, specifying the mode and the ranges that will define each of the isolines. The following query calculates isolines for areas that are 5, 10 and 15 minutes (300, 600 and 900 seconds, respectively) away from the location by following a path defined by car routing and inserts them into a table.
```bash
https://{username}.cartodb.com/api/v2/sql?q=INSERT INTO {table} (the_geom) SELECT the_geom FROM cdb_isodistance('POINT(-3.70568 40.42028)'::geometry, 'car', ARRAY[300, 600, 900]::integer[])&api_key={api_key}
```
The following functions provide an isoline generator service, based on time or distance. This service uses the isolines service defined for your account. The default service limits the usage of displayed polygons represented on top of [HERE](https://developer.here.com/coverage-info) maps.
## cdb_isodistance(_source geometry, mode text, range integer[], [options text[]]_)
Displays a contoured line on a map, connecting geometries to a defined area, measured by an equal range of distance (in meters).
#### Arguments
@@ -26,20 +36,16 @@ Name | Type | Description
#### Examples
##### Select the results of the isodistance function
##### Calculate and insert isodistance polygons from a point into another table
```bash
SELECT * FROM cdb_isodistance('POINT(-3.70568 40.42028)'::geometry, 'car', ARRAY[1000,2000]::integer[]);
INSERT INTO {table} (the_geom) SELECT the_geom FROM cdb_isodistance('POINT(-3.70568 40.42028)'::geometry, 'walk', ARRAY[300, 600, 900]::integer[])
```
```bash
SELECT * FROM cdb_isodistance('POINT(-3.70568 40.42028)'::geometry, 'walk', ARRAY[1000]::integer[], ARRAY['mode_traffic=enabled','quality=3']::text[]);
```
##### Select the geometric results of the isodistance function
or equivalently:
```bash
SELECT the_geom FROM cdb_isodistance('POINT(-3.70568 40.42028)'::geometry, 'walk', ARRAY[1000]::integer[]);
INSERT INTO {table} (the_geom) SELECT (cdb_isodistance('POINT(-3.70568 40.42028)'::geometry, 'walk', ARRAY[300, 600, 900]::integer[])).the_geom
```
##### Calculate and insert the generated isolines from `points_table` table to another table
@@ -48,7 +54,10 @@ SELECT the_geom FROM cdb_isodistance('POINT(-3.70568 40.42028)'::geometry, 'walk
INSERT INTO {table} (the_geom) SELECT (cdb_isodistance(the_geom, 'walk', string_to_array(distance, ',')::integer[])).the_geom FROM {points_table}
```
### cdb_isochrone(_source geometry, mode text, range integer[], [options text[]]_)
## cdb_isochrone(_source geometry, mode text, range integer[], [options text[]]_)
Displays a contoured line on a map, connecting geometries to a defined area, measured by an equal range of time (in seconds).
#### Arguments
@@ -63,23 +72,19 @@ Name | Type | Description | Accepted values
#### Examples
##### Select the results of the isochrone function
##### Calculate and insert isochrone polygons from a point into another table
```bash
SELECT * FROM cdb_isochrone('POINT(-3.70568 40.42028)'::geometry, 'car', ARRAY[300,900,12000]::integer[]);
INSERT INTO {table} (the_geom) SELECT the_geom FROM cdb_isochrone('POINT(-3.70568 40.42028)'::geometry, 'car', ARRAY[300, 900, 12000]::integer[], ARRAY['mode_traffic=enabled','quality=3']::text[])
```
or equivalently:
```bash
SELECT * FROM cdb_isochrone('POINT(-3.70568 40.42028)'::geometry, 'walk', ARRAY[300,900]::integer[], ARRAY['mode_traffic=enabled','quality=3']::text[]);
INSERT INTO {table} (the_geom) SELECT (cdb_isochrone('POINT(-3.70568 40.42028)'::geometry, 'car', ARRAY[300, 900, 12000]::integer[], ARRAY['mode_traffic=enabled','quality=3']::text[])).the_geom
```
##### Select the geometric results of the isochrone function
```bash
SELECT the_geom FROM cdb_isochrone('POINT(-3.70568 40.42028)'::geometry, 'walk', ARRAY[300]::integer[]);
```
##### Calculate and insert the generated isolines from `points_table` table to another table
##### Calculate and insert the generated isolines from `points_table` table into another table
```bash
INSERT INTO {table} (the_geom) SELECT (cdb_isochrone(the_geom, 'walk', string_to_array(time_distance, ',')::integer[])).the_geom FROM {points_table}

49
doc/overview.md Normal file
View File

@@ -0,0 +1,49 @@
# Overview
By using CartoDB libraries and the SQL API, you can apply location data services to your maps with unique data services functions. These functions are integrated with a number of internal and external services, enabling you to programatically customize subsets of data for your visualizations. These features are useful for geospatial analysis and the results can be saved, and stored, for additional location data service operations.
**Note:** Based on your account plan, some of these data services are subject to different [quota limitations](http://docs.cartodb.com/cartodb-platform/dataservices-api/quota-information/#quota-information).
_The Data Services API is collaborating with [Mapzen](https://mapzen.com/), and several other geospatial service providers, in order to supply the best location data services from within our CartoDB Platform._
## Data Services Integration
By using the SQL API to query the Data Services API functions, you can manage specific operations and the corresponding geometries (a `polygon` or a `point`), according to the input information.
The Data Services API decouples the geocoding and isoline services from the CartoDB Editor. The API allows you to geocode data (from single rows, complete datasets, or simple inputs) and to perform trade areas analysis (computing isodistances or isochrones) programatically, through authenticated requests.
The geometries provided by this API are projected in the projection [WGS 84 SRID 4326](http://spatialreference.org/ref/epsg/wgs-84/).
**Note:** The Data Services API [geocoding functions](http://docs.cartodb.com/cartodb-platform/dataservices-api/geocoding-functions/#geocoding-functions) return different types of geometries (points or polygons) as result of different geocoding processes. The CartoDB Platform does not support multi-geometry layers or datasets, therefore you must confirm that you are using consistent geometry types inside a table, to avoid future conflicts in your map visualization.
### Best Practices
_Be mindful of the following usage notes when using the Data Services functions with the SQL API:_
It is discouraged to use the SELECT operation with the Data Services API functions in your map layers, as these type of queries consume quota when rendering tiles for your live map views. It may also result in sync performance issues, due to executing multiple requests to the API each time your map is viewed. See details about [Quota Consumption](http://docs.cartodb.com/cartodb-platform/dataservices-api/quota-information/#quota-consumption).
The Data Services API is **recommended** to be used with INSERT or UPDATE operations, for applying location data to your tables. While SELECT (retrieve) is standard for SQL API requests, be mindful of quota consumption and use INSERT (to insert a new record) or UPDATE (to update an existing record), for best practices.
## Authentication
All requests performed to the CartoDB Data Services API must be authenticated with the user API Key. For more information about where to find your API Key, and how to authenticate your SQL API requests, view the [SQL API authentication](/cartodb-platform/sql-api/authentication/) documentation.
## Errors
Errors are described in the response of the request. An example is as follows:
```json
{
error: [
"The api_key must be provided"
]
}
```
Since the Data Services API is used on top of the CartoDB SQL API, you can refer to the [Making calls to the SQL API](/cartodb-platform/sql-api/making-calls/) documentation for help debugging your SQL errors.
If the requested information is not in the CartoDB geocoding database, or if CartoDB is unable to recognize your input and match it with a result, the geocoding function returns `null` as a result.
## Limits
Usage of the Data Services API is subject to the CartoDB SQL API limits, stated in our [Terms of Service](https://cartodb.com/terms/#excessive).

View File

@@ -1,26 +0,0 @@
# Quickstart
If you are using the set of APIs and libraries that CartoDB offers, and you are handling your data with the SQL API, you can make your data visible in your maps by geocoding the dataset programatically. The set of isoline functions allow you to calculate the area which can be reached by travelling a given distance or time, useful for geospatial analysis, such as Trade Area Analysis.
Here is an example of how to geocode a single country:
```bash
https://{username}.cartodb.com/api/v2/sql?q=SELECT cdb_geocode_admin0_polygon('USA')&api_key={Your API key}
```
In order to geocode an existent CartoDB dataset, an SQL UPDATE statement must be used to populate the geometry column in the dataset with the results of the Geocoding API. For example, if the column where you are storing the country names for each one of our rows is called `country_column`, run the following statement in order to geocode the dataset:
```bash
https://{username}.cartodb.com/api/v2/sql?q=UPDATE {tablename} SET the_geom = cdb_geocode_admin0_polygon({country_column})&api_key={Your API key}
```
You can use the isoline functions to retrieve, for example, isochrone lines from a certain location, specifying the mode and the ranges that will define each of the isolines. The following query calculates isolines for areas that are 5, 10 and 15 minutes (300, 600 and 900 seconds, respectively) away from the location by following a path defined by car routing.
```bash
https://{username}.cartodb.com/api/v2/sql?q=SELECT cdb_isochrone('POINT(-3.70568 40.42028)'::geometry, 'car', ARRAY[300,600,900]::integer[])&api_key={Your API key}
```
Notice that you can make use of Postgres or PostGIS functions in your Data Services API requests, as the result is a geometry that can be handled by the system. For example, suppose you need to retrieve the centroid of a specific country, you can wrap the resulting geometry from the geocoder functions inside the PostGIS `ST_Centroid` function:
```bash
https://{username}.cartodb.com/api/v2/sql?q=SELECT ST_Centroid(cdb_geocode_admin0_polygon('USA'))&api_key={Your API key}
```

View File

@@ -1,17 +1,14 @@
# Quota Information
**This Data Services API provides functions which are subject to quota limitations, and extra fees may apply**. Please check our [terms and conditions](https://cartodb.com/terms/).
**Based on your account plan, some of the Data Services API functions are subject to quota limitations and extra fees may apply.** View our [terms and conditions](https://cartodb.com/terms/), or [contact us](mailto:sales@cartodb.com) for details about which functions require service credits to your account.
The functions that require service credits to be used are as follows:
## Quota Consumption
* cdb_geocode_street_point(_search_text text, [city text], [state text], [country text]_); from [Geocoding functions](http://docs.cartodb.com/cartodb-platform/dataservices-api/geocoding-functions/)
* cdb_isodistance(_source geometry, mode text, range integer[], [options text[]]_); from [Isoline functions](http://docs.cartodb.com/cartodb-platform/dataservices-api/isoline-functions/)
* cdb_isochrone(_source geometry, mode text, range integer[], [options text[]]_); from [Isoline functions](http://docs.cartodb.com/cartodb-platform/dataservices-api/isoline-functions/)
Quota consumption is calculated based on the number of request made for each function. Be mindful of the following usage recommendations when using the Data Services API functions:
## Quota consumption information and usage recommendations
* One credit per function call will be consumed. The results are not cached. If the query is applied to a _N_ rows dataset, then _N_ credits are consumed
* Avoid running dynamic queries to these functions in your maps. This can result in credit consumption per map view.
Be mindful of the following when using the abovementioned functions:
**Note:** Queries to the Data Services API, and any of its functions in your maps, may be forbidden in the future
* One credit per function call will be consumed, and the results are not cached. If the query is applied to a _N_ rows dataset, then _N_ credits will be used.
* You are discouraged from using dynamic queries to these functions in your maps. This can result in credits consumption per map view. **Note:** Queries to the Data Services API and any of its functions in your maps may be forbidden in the future.
* You are advised to store results of these queries into your datasets and refresh them as needed, so that you can have finer control on your credits' usage.
* It is advised to store results of these queries into your datasets, and refresh them as needed. This ensure more control of quota credits for your account

85
doc/routing_functions.md Normal file
View File

@@ -0,0 +1,85 @@
# 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 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]_)
Returns a route from origin to destination.
#### Arguments
Name | Type | Description | Accepted values
--- | --- | --- | ---
`origin` | `geometry(Point)` | Origin point, in 4326 projection, which defines the start location. |
`destination` | `geometry(Point)` | Destination point, in 4326 projection, which defines the end location. |
`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.
#### 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_point_to_point('POINT(-3.70237112 40.41706163)'::geometry,'POINT(-3.69909883 40.41236875)'::geometry, 'car')
```
##### Update the geometry field with the calculated route shape
```bash
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
The optional value parameters must be passed using the format: `option=value`.
Name | Type | Description | Accepted values
--- | --- | --- | ---
`mode_type` | `text` | Type of route calculation | `shortest` (this option only applies to the car transport mode)

View File

@@ -0,0 +1,181 @@
# Segmentation Functions
The Segmentation Snapshot functions enable you to determine the pre-calculated population segment for a location. Segmentation is a method that divides a populations into subclassifications based on common traits. For example, you can take the a store location and determine what classification of population exists around that location. If you need help creating coordinates from addresses, see the [Geocoding Functions](/cartodb-platform/dataservices-api/geocoding-functions/) documentation.
_**Note:** The Segmentation Snapshot functions are only available for the United States. Our first release (May 18, 2016) is derived from Census 2010 variables. Our next release will be based on Census 2014 data. For the latest information, see the [Open Segments](https://github.com/CartoDB/open-segments) project repository._
## OBS_GetSegmentSnapshot( Point Geometry )
### Arguments
Name | Description | Example Values
--- | --- | ---
point geometry | A point geometry. You can use the helper function, `CDB_LatLng` to quickly generate one from latitude and longitude | `CDB_LatLng(40.760410,-73.964242)`
### Returns
The segmentation function returns two segment levels for the point you requests, the x10\_segment and x55\_segment. These segmentation levels contain different classifications of population within with each segment. The function also returns the quantile of a number of census variables. For example, if total_poulation is at 90% quantile level then this tract has a higher total population than 90% of the other tracts.
Name | Type | Description
---- | ---- | -----------
x10\_segment | text | The demographic segment location at the 10 segment level, containing populations at high-levels, broken down into 10 broad categories
x55\_segment | text | The demographic segment location at the 55 segment level, containing more granular sub-levels to categorize the population
An example response appears as follows:
```json
obs_getsegmentsnapshot: {
"x10_segment": "Wealthy, urban without Kids",
"x55_segment": "Wealthy city commuters",
"us.census.acs.B01001001_quantile": "0.0180540540540541",
"us.census.acs.B01001002_quantile": "0.0279864864864865",
"us.census.acs.B01001026_quantile": "0.016527027027027",
"us.census.acs.B01002001_quantile": "0.507297297297297",
"us.census.acs.B03002003_quantile": "0.133162162162162",
"us.census.acs.B03002004_quantile": "0.283743243243243",
"us.census.acs.B03002006_quantile": "0.683945945945946",
"us.census.acs.B03002012_quantile": "0.494594594594595",
"us.census.acs.B05001006_quantile": "0.670972972972973",
"us.census.acs.B08006001_quantile": "0.0607567567567568",
"us.census.acs.B08006002_quantile": "0.0684324324324324",
"us.census.acs.B08006008_quantile": "0.565135135135135",
"us.census.acs.B08006009_quantile": "0.638081081081081",
"us.census.acs.B08006011_quantile": "0",
"us.census.acs.B08006015_quantile": "0.900932432432432",
"us.census.acs.B08006017_quantile": "0.186648648648649",
"us.census.acs.B09001001_quantile": "0.0193513513513514",
"us.census.acs.B11001001_quantile": "0.0617972972972973",
"us.census.acs.B14001001_quantile": "0.0179594594594595",
"us.census.acs.B14001002_quantile": "0.0140405405405405",
"us.census.acs.B14001005_quantile": "0",
"us.census.acs.B14001006_quantile": "0",
"us.census.acs.B14001007_quantile": "0",
"us.census.acs.B14001008_quantile": "0.0609054054054054",
"us.census.acs.B15003001_quantile": "0.0314594594594595",
"us.census.acs.B15003017_quantile": "0.0403378378378378",
"us.census.acs.B15003022_quantile": "0.285972972972973",
"us.census.acs.B15003023_quantile": "0.214567567567568",
"us.census.acs.B16001001_quantile": "0.0181621621621622",
"us.census.acs.B16001002_quantile": "0.0463108108108108",
"us.census.acs.B16001003_quantile": "0.540540540540541",
"us.census.acs.B17001001_quantile": "0.0237567567567568",
"us.census.acs.B17001002_quantile": "0.155972972972973",
"us.census.acs.B19013001_quantile": "0.380662162162162",
"us.census.acs.B19083001_quantile": "0.986891891891892",
"us.census.acs.B19301001_quantile": "0.989594594594595",
"us.census.acs.B25001001_quantile": "0.998418918918919",
"us.census.acs.B25002003_quantile": "0.999824324324324",
"us.census.acs.B25004002_quantile": "0.999986486486486",
"us.census.acs.B25004004_quantile": "0.999662162162162",
"us.census.acs.B25058001_quantile": "0.679054054054054",
"us.census.acs.B25071001_quantile": "0.569716216216216",
"us.census.acs.B25075001_quantile": "0.0415",
"us.census.acs.B25075025_quantile": "0.891702702702703"
}
```
The possible segments are:
<table>
<tr><th> X10 segment</th> <th> X55 Segment </th></tr>
<tr><td> Hispanic and kids</td><td></td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #99C945'></div> Middle Class, Educated, Suburban, Mixed Race </td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #a3ce57'></div> Low Income on Urban Periphery</td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #add468'></div> Suburban, Young and Low-income </td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #b7d978'></div> low-income, urban, young, unmarried </td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #c1df88'></div> Low education, mainly suburban </td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #cbe598'></div> Young, working class and rural </td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #d5eba8'></div> Low-Income with gentrification </td></tr>
<tr><td>Low Income and Diverse</td><td></td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #52BCA3'></div> High school education Long Commuters, Black, White Hispanic mix</td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #66c5ae'></div> Rural, Bachelors or college degree, Rent owned mix</td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #79cdb7'></div> Rural,High School Education, Owns property</td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #8bd5c1'></div> Young, City based renters in Sparse neighborhoods, Low poverty </td></tr>
<tr><td>Low income, minority mix</td><td></td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #5D69B1'></div> Predominantly black, high high school attainment, home owners </td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #7b83c6'></div> White and minority mix multilingual, mixed income / education. Married </td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #9095d2'></div> Hispanic Black mix multilingual, high poverty, renters, uses public transport</td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #a3a7df'></div> Predominantly black renters, rent own mix </td></tr>
<tr><td>Middle income, single family homes</td><td></td></tr>
<tr><td></td> <td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #E58606'></div> Lower Middle Income with higher rent burden </td></tr>
<tr><td></td> <td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #f0983b'></div> Black and mixed community with rent burden</td></tr>
<tr><td></td> <td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #f4a24e'></div> Lower Middle Income with affordable housing</td></tr>
<tr><td></td> <td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #f8ab5f'></div> Relatively affordable, satisfied lower middle class</td></tr>
<tr><td></td> <td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #fcb470'></div> Satisfied Lower Middle Income Higher Rent Costs</td></tr>
<tr><td></td> <td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #ffbe81'></div> Suburban/Rural Satisfied, decently educated lower middle class</td></tr>
<tr><td></td> <td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #ffc792'></div> Struggling lower middle class with rent burden</td></tr>
<tr><td></td> <td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #ffd0a3'></div> Older white home owners, less comfortable financially </td></tr>
<tr><td></td> <td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #ffdab4'></div> Older home owners, more financially comfortable, some diversity</td></tr>
<tr><td>Native American</td><td></td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #2F8AC4'></div>Younger, poorer,single parent family Native Americans</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background: #77b8ee'></div>Older, middle income Native Americans once married and Educated </td></tr>
<tr><td>Old Wealthy, White</td><td></td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#24796C'></div> Older, mixed race professionals</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#388d7e'></div> Works from home, Highly Educated, Super Wealthy </td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#4ca191'></div> Retired Grandparents</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#60b5a5'></div> Wealthy and Rural Living</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#73c9b8'></div> Wealthy, Retired Mountains/Coasts</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#87decc'></div> Wealthy Diverse Suburbanites On the Coasts</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#9bf3e1'></div> Retirement Communitties</td></tr>
<tr><td>Low Income African American</td><td></td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#c23a7e'></div>Urban - Inner city</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#d86298'></div>Rural families</td></tr>
<tr><td>Residential institutions, young people</td><td></td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#764e9f'></div>College towns</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#8a64b1'></div>College town with poverty</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#9e7ac3'></div>University campus wider area</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#b491d5'></div>City Outskirt University Campuses</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#c9a8e8'></div>City Center University Campuses</td></tr>
<tr><td>Wealthy Nuclear Families</td><td></td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#ed645a'></div>Lower educational attainment, Homeowner, Low rent</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#ee7655'></div>Younger, Long Commuter in dense neighborhood</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#f38060'></div>Long commuters White black mix</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#f98a6b'></div>Low rent in built up neighborhoods</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#fe9576'></div>Renters within cities, mixed income areas, White/Hispanic mix, Unmarried</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#ff9f82'></div>Older Home owners with high income</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#ffa98d'></div>Older home owners and very high income</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#ffb399'></div>White Asian Mix Big City Burbs Dwellers</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#ffbda5'></div>Bachelors degree Mid income With Mortgages</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#ffc8b1'></div>Asian Hispanic Mix, Mid income</td></tr>
<tr><td></td><td><div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#ffd2bd'></div>Bachelors degree Higher income Home Owners</td></tr>
<tr><td>Wealthy, urban, and kid-free</td><td></td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#CC61B0'></div>Wealthy city commuters </td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#d975bd'></div>New Developments</td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#e488c9'></div>Very wealthy, multiple million dollar homes</td></tr>
<tr><td></td> <td> <div style='float:left;margin-right:10px;width:20px; height:20px; border-radius:20px;background:#ee9ad4'></div>High rise, dense urbanites</td></tr>
</table>
### Examples
```bash
https://{username}.cartodb.com/api/v2/sql?q=SELECT * FROM
OBS_GetSegmentSnapshot({{point geometry}})
```
##### Get the Geographic Snapshot of a Segmentation
__Get the Segmentation Snapshot around the MGM Grand__
```bash
https://{username}.cartodb.com/api/v2/sql?q=SELECT * FROM
OBS_GetSegmentSnapshot(CDB_LatLng(36.10222, -115.169516))
```
__Get the Segmentation Snapshot at CartoDB's NYC HQ__
```bash
https://{username}.cartodb.com/api/v2/sql?q=SELECT * FROM
OBS_GetSegmentSnapshot(CDB_LatLng(40.704512, -73.936669))
```

View File

@@ -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.6.2--0.7.0.sql \
cdb_dataservices_server--0.7.0--0.6.2.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/

View 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;

View 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;

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
comment = 'CartoDB dataservices server extension'
default_version = '0.7.0'
requires = 'plpythonu, postgis, cdb_geocoder'
default_version = '0.9.0'
requires = 'plpythonu, plproxy, postgis, cdb_geocoder'
superuser = true
schema = cdb_dataservices_server

View File

@@ -0,0 +1,94 @@
--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.7.1'" to load this file. \quit
DROP FUNCTION IF EXISTS cdb_dataservices_server._get_data_observatory_config(text, text);
CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_obs_snapshot_config(username text, orgname text)
RETURNS boolean AS $$
cache_key = "user_obs_snapshot_config_{0}".format(username)
if cache_key in GD:
return False
else:
from cartodb_services.metrics import ObservatorySnapshotConfig
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection']
obs_snapshot_config = ObservatorySnapshotConfig(redis_conn, plpy, username, orgname)
GD[cache_key] = obs_snapshot_config
return True
$$ LANGUAGE plpythonu SECURITY DEFINER;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT '2009 - 2013',
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_observatory.OBS_GetDemographicSnapshot($1, $2, $3) as snapshot;", ["geometry(Geometry, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [geom, time_span, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_observatory.OBS_GetSegmentSnapshot($1, $2) as snapshot;", ["geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [geom, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_segment_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;

View File

@@ -1,3 +1,21 @@
--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.7.0'" to load this file. \quit
DROP FUNCTION IF EXISTS cdb_dataservices_server._get_obs_snapshot_config(text, text);
CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_data_observatory_config(username text, orgname text)
RETURNS boolean AS $$
cache_key = "user_data_observatory_config_{0}".format(username)
if cache_key in GD:
return False
else:
from cartodb_services.metrics import DataObservatoryConfig
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection']
data_observatory_config = DataObservatoryConfig(redis_conn, plpy, username, orgname)
GD[cache_key] = data_observatory_config
return True
$$ LANGUAGE plpythonu SECURITY DEFINER;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
@@ -31,7 +49,7 @@ RETURNS json AS $$
type_, value_, traceback_ = sys.exc_info()
quota_service.increment_failed_service_use()
error_msg = 'There was an error trying to use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.notice(traceback.format_exception(type_, value_, traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()

View File

@@ -0,0 +1,115 @@
--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.7.2'" to load this file. \quit
DROP FUNCTION IF EXISTS cdb_dataservices_server.obs_get_demographic_snapshot(text, text, geometry(Geometry, 4326), text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_server.obs_get_segment_snapshot(text, text, geometry(Geometry, 4326), text);
CREATE OR REPLACE FUNCTION cdb_dataservices_server._obs_server_conn_str(
username TEXT,
orgname TEXT
)
RETURNS text 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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
return user_obs_snapshot_config.connection_str
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT '2009 - 2013',
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_dataservices_server._obs_get_demographic_snapshot (username, orgname, geom, time_span, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT '2009 - 2013',
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_observatory.OBS_GetDemographicSnapshot($1, $2, $3) as snapshot;", ["geometry(Geometry, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [geom, time_span, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_dataservices_server._obs_get_segment_snapshot (username, orgname, geom, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._obs_get_segment_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_observatory.OBS_GetSegmentSnapshot($1, $2) as snapshot;", ["geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [geom, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_segment_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,84 @@
--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.7.1'" to load this file. \quit
DROP FUNCTION IF EXISTS cdb_dataservices_server._obs_server_conn_str(text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_server.obs_get_demographic_snapshot(text, text, geometry(Geometry, 4326), text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_server.obs_get_segment_snapshot(text, text, geometry(Geometry, 4326), text);
DROP FUNCTION IF EXISTS cdb_dataservices_server._obs_get_demographic_snapshot(text, text, geometry(Geometry, 4326), text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_server._obs_get_segment_snapshot(text, text, geometry(Geometry, 4326), text);
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT '2009 - 2013',
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_observatory.OBS_GetDemographicSnapshot($1, $2, $3) as snapshot;", ["geometry(Geometry, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [geom, time_span, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_observatory.OBS_GetSegmentSnapshot($1, $2) as snapshot;", ["geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [geom, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_segment_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;

View File

@@ -0,0 +1,113 @@
--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.7.3'" to load this file. \quit
CREATE OR REPLACE FUNCTION cdb_dataservices_server._obs_server_conn_str(
username TEXT,
orgname TEXT)
RETURNS text 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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
return user_obs_snapshot_config.connection_str
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT '2009 - 2013',
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT '2009 - 2013',
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshot($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetSegmentSnapshot($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_segment_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,103 @@
--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.7.2'" to load this file. \quit
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetDemographicSnapshot(text, text, geometry(Geometry, 4326), text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetSegmentSnapshot(text, text, geometry(Geometry, 4326), text);
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT '2009 - 2013',
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_dataservices_server._obs_get_demographic_snapshot (username, orgname, geom, time_span, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT '2009 - 2013',
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_observatory.OBS_GetDemographicSnapshot($1, $2, $3) as snapshot;", ["geometry(Geometry, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [geom, time_span, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_dataservices_server._obs_get_segment_snapshot (username, orgname, geom, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._obs_get_segment_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_observatory.OBS_GetSegmentSnapshot($1, $2) as snapshot;", ["geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [geom, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_segment_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;

View File

@@ -0,0 +1,57 @@
--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.7.4'" to load this file. \quit
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_here_routing_isolines(username TEXT, orgname TEXT, type TEXT, source geometry(Geometry, 4326), mode TEXT, data_range integer[], options text[])
RETURNS SETOF cdb_dataservices_server.isoline AS $$
import json
from cartodb_services.here import HereMapsRoutingIsoline
from cartodb_services.metrics import QuotaService
from cartodb_services.here.types import geo_polyline_to_multipolygon
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)]
# -- Check the quota
quota_service = QuotaService(user_isolines_routing_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
client = HereMapsRoutingIsoline(user_isolines_routing_config.heremaps_app_id, user_isolines_routing_config.heremaps_app_code, base_url = HereMapsRoutingIsoline.PRODUCTION_ROUTING_BASE_URL)
if source:
lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat']
lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon']
source_str = 'geo!%f,%f' % (lat, lon)
else:
source_str = None
if type == 'isodistance':
resp = client.calculate_isodistance(source_str, mode, data_range, options)
elif type == 'isochrone':
resp = client.calculate_isochrone(source_str, mode, data_range, options)
if resp:
result = []
for isoline in resp:
data_range_n = isoline['range']
polyline = isoline['geom']
multipolygon = geo_polyline_to_multipolygon(polyline)
result.append([source, data_range_n, multipolygon])
quota_service.increment_success_service_use()
quota_service.increment_isolines_service_use(len(resp))
return result
else:
quota_service.increment_empty_service_use()
return []
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 isodistances using here maps geocoder: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu SECURITY DEFINER;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
--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.7.3'" to load this file. \quit
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_here_routing_isolines(username TEXT, orgname TEXT, type TEXT, source geometry(Geometry, 4326), mode TEXT, data_range integer[], options text[])
RETURNS SETOF cdb_dataservices_server.isoline AS $$
import json
from cartodb_services.here import HereMapsRoutingIsoline
from cartodb_services.metrics import QuotaService
from cartodb_services.here.types import geo_polyline_to_multipolygon
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)]
# -- Check the quota
quota_service = QuotaService(user_isolines_routing_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
client = HereMapsRoutingIsoline(user_isolines_routing_config.heremaps_app_id, user_isolines_routing_config.heremaps_app_code, base_url = HereMapsRoutingIsoline.PRODUCTION_ROUTING_BASE_URL)
if source:
lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat']
lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon']
source_str = 'geo!%f,%f' % (lat, lon)
else:
source_str = None
if type == 'isodistance':
resp = client.calculate_isodistance(source_str, mode, data_range, options)
elif type == 'isochrone':
resp = client.calculate_isochrone(source_str, mode, data_range, options)
if resp:
result = []
for isoline in resp:
data_range_n = isoline['range']
polyline = isoline['geom']
multipolygon = geo_polyline_to_multipolygon(polyline)
result.append([source, data_range_n, multipolygon])
quota_service.increment_success_service_use()
quota_service.increment_isolines_service_use(len(resp))
return result
else:
quota_service.increment_empty_service_use()
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 isodistances using here maps geocoder: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu SECURITY DEFINER;

View File

@@ -0,0 +1,966 @@
--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._OBS_GetDemographicSnapshot(text, text, geometry(Geometry, 4326), text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetSegmentSnapshot(text, text, geometry(Geometry, 4326), text);
CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_obs_config(username text, orgname text)
RETURNS boolean AS $$
cache_key = "user_obs_config_{0}".format(username)
if cache_key in GD:
return False
else:
from cartodb_services.metrics import ObservatoryConfig
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection']
obs_config = ObservatoryConfig(redis_conn, plpy, username, orgname)
GD[cache_key] = obs_config
return True
$$ LANGUAGE plpythonu SECURITY DEFINER;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshotJSON(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL,
geometry_level TEXT DEFAULT NULL)
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL,
geometry_level TEXT DEFAULT NULL)
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshotJSON($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL,
geometry_level TEXT DEFAULT NULL)
RETURNS SETOF json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetDemographicSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL,
geometry_level TEXT DEFAULT NULL)
RETURNS SETOF JSON AS $$
from cartodb_services.metrics import QuotaService
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshot($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level])
if result:
resp = []
for element in result:
value = element['snapshot']
resp.append(value)
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshotJSON(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT NULL)
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT NULL)
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetSegmentSnapshotJSON($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_segment_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT NULL)
RETURNS SETOF json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetSegmentSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT NULL)
RETURNS SETOF JSON AS $$
from cartodb_services.metrics import QuotaService
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetSegmentSnapshot($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level])
if result:
resp = []
for element in result:
value = element['snapshot']
resp.append(value)
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use get_segment_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetMeasure(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
measure_id TEXT,
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetMeasure(geom, measure_id, normalize, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetMeasure(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
measure_id TEXT,
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetMeasure($1, $2, $3, $4, $5, $6, $7) as measure;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, measure_id, normalize, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['measure']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetMeasure: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetCategory(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
category_id TEXT,
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetCategory(geom, category_id, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetCategory(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
category_id TEXT,
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetCategory($1, $2, $3, $4, $5, $6) as category;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, category_id, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['category']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetCategory: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetUSCensusMeasure(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
name TEXT,
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetUSCensusMeasure(geom, name, normalize, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetUSCensusMeasure(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
name TEXT,
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetUSCensusMeasure($1, $2, $3, $4, $5, $6, $7) as census_measure;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, name, normalize, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['census_measure']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetUSCensusMeasure: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetUSCensusCategory(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
name TEXT,
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetUSCensusCategory(geom, name, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetUSCensusCategory(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
name TEXT,
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetUSCensusCategory($1, $2, $3, $4, $5, $6) as census_category;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, name, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['census_category']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetUSCensusCategory: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPopulation(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetPopulation(geom, normalize, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPopulation(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetPopulation($1, $2, $3, $4, $5, $6) as population;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, normalize, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['population']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetPopulation: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_Search(
username TEXT,
orgname TEXT,
search_term TEXT,
relevant_boundary TEXT DEFAULT NULL)
RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_Search(search_term, relevant_boundary);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_Search(
username TEXT,
orgname TEXT,
search_term TEXT,
relevant_boundary TEXT DEFAULT NULL)
RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_Search($1, $2, $3, $4) as search;", ["text", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, search_term, relevant_boundary])
if result:
resp = []
for element in result:
id = element['id']
description = element['description']
name = element['name']
aggregate = element['aggregate']
source = element['source']
resp.append([id, description, name, aggregate, source])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use OBS_Search: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetAvailableBoundaries(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL)
RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetAvailableBoundaries(geom, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableBoundaries(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL)
RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetAvailableBoundaries($1, $2, $3, $4) as available_boundaries;", ["text", "text", "geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, time_span])
if result:
resp = []
for element in result:
id = element['boundary_id']
description = element['description']
tspan = element['time_span']
tablename = element['tablename']
resp.append([id, description, tspan, tablename])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use OBS_GetAvailableBoundaries: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundary(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS geometry(Geometry, 4326) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetBoundary(geom, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundary(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS geometry(Geometry, 4326) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundary($1, $2, $3, $4) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['boundary']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetBoundary: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundaryId(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetBoundaryId(geom, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundaryId(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundaryId($1, $2, $3, $4, $5) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['boundary']
else:
quota_service.increment_empty_service_use()
return 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 use obs_search: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundaryById(
username TEXT,
orgname TEXT,
geometry_id TEXT,
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS geometry(Geometry, 4326) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetBoundaryById(geometry_id, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundaryById(
username TEXT,
orgname TEXT,
geometry_id TEXT,
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS geometry(Geometry, 4326) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundaryById($1, $2, $3, $4, $5) as boundary;", ["text", "text", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geometry_id, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['boundary']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetBoundaryById: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundariesByGeometry(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type text DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetBoundariesByGeometry(geom, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundariesByGeometry(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetBoundariesByGeometry($1, $2, $3, $4, $5, $6) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span, overlap_type])
if result:
resp = []
for element in result:
the_geom = element['the_geom']
geom_refs = element['geom_refs']
resp.append([the_geom, geom_refs])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use OBS_GetBoundariesByGeometry: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
radius NUMERIC,
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetBoundariesByPointAndRadius(geom, radius, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundariesByPointAndRadius(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
radius NUMERIC,
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius($1, $2, $3, $4, $5, $6, $7) as boundary;", ["text", "text", "geometry(Point, 4326)", "numeric", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, radius, boundary_id, time_span, overlap_type])
if result:
resp = []
for element in result:
the_geom = element['the_geom']
geom_refs = element['geom_refs']
resp.append([the_geom, geom_refs])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use OBS_GetBoundariesByPointAndRadius: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPointsByGeometry(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetPointsByGeometry(geom, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPointsByGeometry(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetPointsByGeometry($1, $2, $3, $4, $5, $6) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span, overlap_type])
if result:
resp = []
for element in result:
the_geom = element['the_geom']
geom_refs = element['geom_refs']
resp.append([the_geom, geom_refs])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use OBS_GetPointsByGeometry: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPointsByPointAndRadius(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
radius NUMERIC,
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetPointsByPointAndRadius(geom, radius, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPointsByPointAndRadius(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
radius NUMERIC,
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetPointsByPointAndRadius($1, $2, $3, $4, $5, $6, $7) as boundary;", ["text", "text", "geometry(Point, 4326)", "numeric", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, radius, boundary_id, time_span, overlap_type])
if result:
resp = []
for element in result:
the_geom = element['the_geom']
geom_refs = element['geom_refs']
resp.append([the_geom, geom_refs])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetPointsByPointAndRadius: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,138 @@
--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.7.4'" to load this file. \quit
DROP FUNCTION IF EXISTS cdb_dataservices_server._get_obs_config(text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetDemographicSnapshot(text, text, geometry(Geometry, 4326), text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetDemographicSnapshotJSON(text, text, geometry(Geometry, 4326), text, text);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetDemographicSnapshot(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetSegmentSnapshot(text, text, geometry(Geometry, 4326), text);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetSegmentSnapshotJSON(text, text, geometry(Geometry, 4326), text);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetSegmentSnapshot(TEXT, TEXT, geometry(Geometry, 4326), TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetMeasure(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetMeasure(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetCategory(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetCategory(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetUSCensusMeasure(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetUSCensusMeasure(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetUSCensusCategory(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetUSCensusCategory(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetPopulation(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetPopulation(TEXT, TEXT, geometry(Geometry, 4326), TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_Search(TEXT, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_Search(TEXT, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetAvailableBoundaries(TEXT, TEXT, geometry(Geometry, 4326), TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetAvailableBoundaries(TEXT, TEXT, geometry(Geometry, 4326), TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetBoundary(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundary(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetBoundaryId(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundaryId(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetBoundaryById(TEXT, TEXT, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundaryById(TEXT, TEXT, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetBoundariesByGeometry(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundariesByGeometry(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetBoundariesByPointAndRadius(TEXT, TEXT, NUMERIC, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius(TEXT, TEXT, NUMERIC, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetPointsByGeometry(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetPointsByGeometry(TEXT, TEXT, geometry(Point, 4326), TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server.OBS_GetPointsByPointAndRadius(TEXT, TEXT, geometry(Point, 4326), NUMERIC, TEXT, TEXT, TEXT);
DROP FUNCTION IF EXISTS cdb_dataservices_server._OBS_GetPointsByPointAndRadius(TEXT, TEXT, geometry(Point, 4326), NUMERIC, TEXT, TEXT, TEXT);
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT '2009 - 2013',
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT '2009 - 2013',
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshot($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT '"us.census.tiger".block_group')
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetSegmentSnapshot($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_segment_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;

File diff suppressed because it is too large Load Diff

View File

@@ -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:

View 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;

View File

@@ -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;

View File

@@ -0,0 +1,478 @@
--
-- Observatory connection config
--
-- The purpose of this function is provide to the PL/Proxy functions
-- the connection string needed to connect with the current production database
CREATE OR REPLACE FUNCTION cdb_dataservices_server._obs_server_conn_str(
username TEXT,
orgname TEXT)
RETURNS text 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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
return user_obs_snapshot_config.connection_str
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshotJSON(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL,
geometry_level TEXT DEFAULT NULL)
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_demographic_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL,
geometry_level TEXT DEFAULT NULL)
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshotJSON($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetDemographicSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL,
geometry_level TEXT DEFAULT NULL)
RETURNS SETOF json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetDemographicSnapshot(geom, time_span, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetDemographicSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL,
geometry_level TEXT DEFAULT NULL)
RETURNS SETOF JSON AS $$
from cartodb_services.metrics import QuotaService
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetDemographicSnapshot($1, $2, $3, $4, $5) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, time_span, geometry_level])
if result:
resp = []
for element in result:
value = element['snapshot']
resp.append(value)
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use get_geographic_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshotJSON(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT NULL)
RETURNS json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.obs_get_segment_snapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT NULL)
RETURNS json AS $$
from cartodb_services.metrics import QuotaService
import json
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetSegmentSnapshotJSON($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level])
if result:
quota_service.increment_success_service_use()
return result[0]['snapshot']
else:
quota_service.increment_empty_service_use()
return 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 use get_segment_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetSegmentSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT NULL)
RETURNS SETOF json AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetSegmentSnapshot(geom, geometry_level);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetSegmentSnapshot(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
geometry_level TEXT DEFAULT NULL)
RETURNS SETOF JSON AS $$
from cartodb_services.metrics import QuotaService
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_obs_snapshot_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_snapshot_config = GD["user_obs_snapshot_config_{0}".format(username)]
quota_service = QuotaService(user_obs_snapshot_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetSegmentSnapshot($1, $2, $3, $4) as snapshot;", ["text", "text", "geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, geometry_level])
if result:
resp = []
for element in result:
value = element['snapshot']
resp.append(value)
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use get_segment_snapshot: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetMeasure(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
measure_id TEXT,
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetMeasure(geom, measure_id, normalize, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetMeasure(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
measure_id TEXT,
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetMeasure($1, $2, $3, $4, $5, $6, $7) as measure;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, measure_id, normalize, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['measure']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetMeasure: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetCategory(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
category_id TEXT,
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetCategory(geom, category_id, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetCategory(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
category_id TEXT,
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetCategory($1, $2, $3, $4, $5, $6) as category;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, category_id, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['category']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetCategory: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetUSCensusMeasure(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
name TEXT,
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetUSCensusMeasure(geom, name, normalize, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetUSCensusMeasure(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
name TEXT,
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetUSCensusMeasure($1, $2, $3, $4, $5, $6, $7) as census_measure;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, name, normalize, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['census_measure']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetUSCensusMeasure: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetUSCensusCategory(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
name TEXT,
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetUSCensusCategory(geom, name, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetUSCensusCategory(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
name TEXT,
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetUSCensusCategory($1, $2, $3, $4, $5, $6) as census_category;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, name, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['census_category']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetUSCensusCategory: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPopulation(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetPopulation(geom, normalize, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPopulation(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
normalize TEXT DEFAULT 'area',
boundary_id TEXT DEFAULT NULL,
time_span TEXT DEFAULT NULL)
RETURNS NUMERIC AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetPopulation($1, $2, $3, $4, $5, $6) as population;", ["text", "text", "geometry(Geometry, 4326)", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, normalize, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['population']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetPopulation: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;

View File

@@ -0,0 +1,108 @@
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_Search(
username TEXT,
orgname TEXT,
search_term TEXT,
relevant_boundary TEXT DEFAULT NULL)
RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_Search(search_term, relevant_boundary);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_Search(
username TEXT,
orgname TEXT,
search_term TEXT,
relevant_boundary TEXT DEFAULT NULL)
RETURNS TABLE(id text, description text, name text, aggregate text, source text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_Search($1, $2, $3, $4);", ["text", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, search_term, relevant_boundary])
if result:
resp = []
for element in result:
id = element['id']
description = element['description']
name = element['name']
aggregate = element['aggregate']
source = element['source']
resp.append([id, description, name, aggregate, source])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return [None, None, 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 use OBS_Search: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetAvailableBoundaries(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL)
RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetAvailableBoundaries(geom, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetAvailableBoundaries(
username TEXT,
orgname TEXT,
geom geometry(Geometry, 4326),
time_span TEXT DEFAULT NULL)
RETURNS TABLE(boundary_id text, description text, time_span text, tablename text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetAvailableBoundaries($1, $2, $3, $4) as available_boundaries;", ["text", "text", "geometry(Geometry, 4326)", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, time_span])
if result:
resp = []
for element in result:
id = element['boundary_id']
description = element['description']
tspan = element['time_span']
tablename = element['tablename']
resp.append([id, description, tspan, tablename])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use OBS_GetAvailableBoundaries: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;

View File

@@ -0,0 +1,374 @@
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundary(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS geometry(Geometry, 4326) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetBoundary(geom, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundary(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS geometry(Geometry, 4326) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundary($1, $2, $3, $4) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['boundary']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetBoundary: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundaryId(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetBoundaryId(geom, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundaryId(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS TEXT AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundaryId($1, $2, $3, $4, $5) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['boundary']
else:
quota_service.increment_empty_service_use()
return 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 use obs_search: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundaryById(
username TEXT,
orgname TEXT,
geometry_id TEXT,
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS geometry(Geometry, 4326) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT cdb_observatory.OBS_GetBoundaryById(geometry_id, boundary_id, time_span);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundaryById(
username TEXT,
orgname TEXT,
geometry_id TEXT,
boundary_id TEXT,
time_span TEXT DEFAULT NULL)
RETURNS geometry(Geometry, 4326) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT cdb_dataservices_server._OBS_GetBoundaryById($1, $2, $3, $4, $5) as boundary;", ["text", "text", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geometry_id, boundary_id, time_span])
if result:
quota_service.increment_success_service_use()
return result[0]['boundary']
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetBoundaryById: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundariesByGeometry(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type text DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetBoundariesByGeometry(geom, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundariesByGeometry(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetBoundariesByGeometry($1, $2, $3, $4, $5, $6) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span, overlap_type])
if result:
resp = []
for element in result:
the_geom = element['the_geom']
geom_refs = element['geom_refs']
resp.append([the_geom, geom_refs])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use OBS_GetBoundariesByGeometry: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
radius NUMERIC,
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetBoundariesByPointAndRadius(geom, radius, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetBoundariesByPointAndRadius(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
radius NUMERIC,
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetBoundariesByPointAndRadius($1, $2, $3, $4, $5, $6, $7) as boundary;", ["text", "text", "geometry(Point, 4326)", "numeric", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, radius, boundary_id, time_span, overlap_type])
if result:
resp = []
for element in result:
the_geom = element['the_geom']
geom_refs = element['geom_refs']
resp.append([the_geom, geom_refs])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use OBS_GetBoundariesByPointAndRadius: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPointsByGeometry(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetPointsByGeometry(geom, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPointsByGeometry(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetPointsByGeometry($1, $2, $3, $4, $5, $6) as boundary;", ["text", "text", "geometry(Point, 4326)", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, boundary_id, time_span, overlap_type])
if result:
resp = []
for element in result:
the_geom = element['the_geom']
geom_refs = element['geom_refs']
resp.append([the_geom, geom_refs])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return []
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 use OBS_GetPointsByGeometry: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._OBS_GetPointsByPointAndRadius(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
radius NUMERIC,
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
CONNECT cdb_dataservices_server._obs_server_conn_str(username, orgname);
SELECT * FROM cdb_observatory.OBS_GetPointsByPointAndRadius(geom, radius, boundary_id, time_span, overlap_type);
$$ LANGUAGE plproxy;
CREATE OR REPLACE FUNCTION cdb_dataservices_server.OBS_GetPointsByPointAndRadius(
username TEXT,
orgname TEXT,
geom geometry(Point, 4326),
radius NUMERIC,
boundary_id TEXT,
time_span TEXT DEFAULT NULL,
overlap_type TEXT DEFAULT 'intersects')
RETURNS TABLE(the_geom geometry, geom_refs text) AS $$
from cartodb_services.metrics import QuotaService
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_obs_config({0}, {1})".format(plpy.quote_nullable(username), plpy.quote_nullable(orgname)))
user_obs_config = GD["user_obs_config_{0}".format(username)]
quota_service = QuotaService(user_obs_config, redis_conn)
if not quota_service.check_user_quota():
plpy.error('You have reached the limit of your quota')
try:
obs_plan = plpy.prepare("SELECT * FROM cdb_dataservices_server._OBS_GetPointsByPointAndRadius($1, $2, $3, $4, $5, $6, $7) as boundary;", ["text", "text", "geometry(Point, 4326)", "numeric", "text", "text", "text"])
result = plpy.execute(obs_plan, [username, orgname, geom, radius, boundary_id, time_span, overlap_type])
if result:
resp = []
for element in result:
the_geom = element['the_geom']
geom_refs = element['geom_refs']
resp.append([the_geom, geom_refs])
quota_service.increment_success_service_use()
return resp
else:
quota_service.increment_empty_service_use()
return 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 use OBS_GetPointsByPointAndRadius: {0}'.format(e)
plpy.notice(traceback.format_tb(traceback_))
plpy.error(error_msg)
finally:
quota_service.increment_total_service_use()
$$ LANGUAGE plpythonu;

View File

@@ -54,16 +54,30 @@ RETURNS boolean AS $$
return True
$$ LANGUAGE plpythonu SECURITY DEFINER;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_data_observatory_config(username text, orgname text)
CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_obs_snapshot_config(username text, orgname text)
RETURNS boolean AS $$
cache_key = "user_data_observatory_config_{0}".format(username)
cache_key = "user_obs_snapshot_config_{0}".format(username)
if cache_key in GD:
return False
else:
from cartodb_services.metrics import DataObservatoryConfig
from cartodb_services.metrics import ObservatorySnapshotConfig
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection']
data_observatory_config = DataObservatoryConfig(redis_conn, plpy, username, orgname)
GD[cache_key] = data_observatory_config
obs_snapshot_config = ObservatorySnapshotConfig(redis_conn, plpy, username, orgname)
GD[cache_key] = obs_snapshot_config
return True
$$ LANGUAGE plpythonu SECURITY DEFINER;
CREATE OR REPLACE FUNCTION cdb_dataservices_server._get_obs_config(username text, orgname text)
RETURNS boolean AS $$
cache_key = "user_obs_config_{0}".format(username)
if cache_key in GD:
return False
else:
from cartodb_services.metrics import ObservatoryConfig
plpy.execute("SELECT cdb_dataservices_server._connect_to_redis('{0}')".format(username))
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metadata_connection']
obs_config = ObservatoryConfig(redis_conn, plpy, username, orgname)
GD[cache_key] = obs_config
return True
$$ LANGUAGE plpythonu SECURITY DEFINER;

View File

@@ -42,6 +42,7 @@ RETURNS SETOF cdb_dataservices_server.isoline AS $$
return result
else:
quota_service.increment_empty_service_use()
return []
except BaseException as e:
import sys, traceback
type_, value_, traceback_ = sys.exc_info()

View File

@@ -2,6 +2,7 @@
CREATE EXTENSION postgis;
CREATE EXTENSION schema_triggers;
CREATE EXTENSION plpythonu;
CREATE EXTENSION plproxy;
CREATE EXTENSION cartodb;
CREATE EXTENSION cdb_geocoder;
CREATE EXTENSION observatory VERSION 'dev';
@@ -38,7 +39,7 @@ SELECT cartodb.cdb_conf_setconf('logger_conf', '{"geocoder_log_path": "/dev/null
(1 row)
SELECT cartodb.cdb_conf_setconf('data_observatory_conf', '{"monthly_quota": 10000}');
SELECT cartodb.cdb_conf_setconf('data_observatory_conf', '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}, "monthly_quota": 100000}');
cdb_conf_setconf
------------------

View File

@@ -2,7 +2,7 @@ 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 = 'obs_get_demographic_snapshot'
AND proname = 'obs_getdemographicsnapshot'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text');
exists
--------
@@ -13,10 +13,164 @@ 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 = 'obs_get_segment_snapshot'
AND proname = 'obs_getsegmentsnapshot'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text');
exists
--------
t
(1 row)
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 = 'obs_getmeasure'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text, text');
exists
--------
t
(1 row)
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 = 'obs_getcategory'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text');
exists
--------
t
(1 row)
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 = 'obs_getuscensusmeasure'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text, text');
exists
--------
t
(1 row)
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 = 'obs_getuscensuscategory'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text');
exists
--------
t
(1 row)
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 = 'obs_getpopulation'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text');
exists
--------
t
(1 row)
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 = 'obs_search'
AND oidvectortypes(p.proargtypes) = 'text, text, text, text');
exists
--------
t
(1 row)
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 = 'obs_getavailableboundaries'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text');
exists
--------
t
(1 row)
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 = 'obs_getboundary'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text');
exists
--------
t
(1 row)
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 = 'obs_getboundaryid'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text');
exists
--------
t
(1 row)
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 = 'obs_getboundarybyid'
AND oidvectortypes(p.proargtypes) = 'text, text, text, text, text');
exists
--------
t
(1 row)
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 = 'obs_getboundariesbygeometry'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text');
exists
--------
t
(1 row)
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 = 'obs_getboundariesbypointandradius'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, numeric, text, text, text');
exists
--------
t
(1 row)
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 = 'obs_getpointsbygeometry'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text');
exists
--------
t
(1 row)
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 = 'obs_getpointsbypointandradius'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, numeric, text, text, text');
exists
--------
t
(1 row)

View File

@@ -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)

View File

@@ -2,6 +2,7 @@
CREATE EXTENSION postgis;
CREATE EXTENSION schema_triggers;
CREATE EXTENSION plpythonu;
CREATE EXTENSION plproxy;
CREATE EXTENSION cartodb;
CREATE EXTENSION cdb_geocoder;
CREATE EXTENSION observatory VERSION 'dev';
@@ -15,7 +16,7 @@ SELECT cartodb.cdb_conf_setconf('redis_metadata_config', '{"redis_host": "localh
SELECT cartodb.cdb_conf_setconf('heremaps_conf', '{"geocoder": {"app_id": "dummy_id", "app_code": "dummy_code", "geocoder_cost_per_hit": 1}, "isolines": {"app_id": "dummy_id", "app_code": "dummy_code"}}');
SELECT cartodb.cdb_conf_setconf('mapzen_conf', '{"routing": {"api_key": "routing_dummy_api_key", "monthly_quota": 1500000}, "geocoder": {"api_key": "geocoder_dummy_api_key", "monthly_quota": 1500000}}');
SELECT cartodb.cdb_conf_setconf('logger_conf', '{"geocoder_log_path": "/dev/null"}');
SELECT cartodb.cdb_conf_setconf('data_observatory_conf', '{"monthly_quota": 10000}');
SELECT cartodb.cdb_conf_setconf('data_observatory_conf', '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}, "monthly_quota": 100000}');
-- Mock the varnish invalidation function
-- (used by cdb_geocoder tests)

View File

@@ -2,12 +2,110 @@ 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 = 'obs_get_demographic_snapshot'
AND proname = 'obs_getdemographicsnapshot'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text');
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 = 'obs_get_segment_snapshot'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text');
AND proname = 'obs_getsegmentsnapshot'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text');
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 = 'obs_getmeasure'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text, text');
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 = 'obs_getcategory'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text');
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 = 'obs_getuscensusmeasure'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text, text');
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 = 'obs_getuscensuscategory'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text');
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 = 'obs_getpopulation'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text');
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 = 'obs_search'
AND oidvectortypes(p.proargtypes) = 'text, text, text, text');
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 = 'obs_getavailableboundaries'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text');
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 = 'obs_getboundary'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text');
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 = 'obs_getboundaryid'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text');
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 = 'obs_getboundarybyid'
AND oidvectortypes(p.proargtypes) = 'text, text, text, text, text');
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 = 'obs_getboundariesbygeometry'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text');
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 = 'obs_getboundariesbypointandradius'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, numeric, text, text, text');
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 = 'obs_getpointsbygeometry'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, text, text, text');
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 = 'obs_getpointsbypointandradius'
AND oidvectortypes(p.proargtypes) = 'text, text, geometry, numeric, text, text, text');

View File

@@ -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');

View File

@@ -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');

View File

@@ -87,6 +87,8 @@ class HereMapsGeocoder:
response = requests.get(self.host, params=request_params)
if response.status_code == requests.codes.ok:
return json.loads(response.text)
elif response.status_code == requests.codes.bad_request:
return []
else:
response.raise_for_status()

View File

@@ -51,6 +51,8 @@ class HereMapsRoutingIsoline:
response = requests.get(self._url, params=request_params)
if response.status_code == requests.codes.ok:
return self.__parse_isolines_response(response.text)
elif response.status_code == requests.codes.bad_request:
return []
else:
response.raise_for_status()

View File

@@ -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:

View File

@@ -1,3 +1,3 @@
from config import GeocoderConfig, IsolinesRoutingConfig, InternalGeocoderConfig, RoutingConfig, ConfigException, DataObservatoryConfig
from config import GeocoderConfig, IsolinesRoutingConfig, InternalGeocoderConfig, RoutingConfig, ConfigException, ObservatorySnapshotConfig, ObservatoryConfig
from quota import QuotaService
from user import UserMetricsService

View File

@@ -14,9 +14,10 @@ class ServiceConfig(object):
self._redis_connection = redis_connection
self._username = username
self._orgname = orgname
self._db_config = ServicesDBConfig(db_conn)
self._db_config = ServicesDBConfig(db_conn, username, orgname)
if redis_connection:
self._redis_config = ServicesRedisConfig(redis_connection).build(username, orgname)
self._redis_config = ServicesRedisConfig(redis_connection).build(
username, orgname)
else:
self._redis_config = None
@@ -34,17 +35,9 @@ class ServiceConfig(object):
class DataObservatoryConfig(ServiceConfig):
PERIOD_END_DATE = 'period_end_date'
def __init__(self, redis_connection, db_conn, username, orgname=None):
super(DataObservatoryConfig, self).__init__(redis_connection, db_conn,
username, orgname)
self._monthly_quota = self._db_config.data_observatory_monthly_quota
self._period_end_date = date_parse(self._redis_config[self.PERIOD_END_DATE])
@property
def service_type(self):
return 'data_observatory'
@property
def monthly_quota(self):
@@ -54,6 +47,59 @@ class DataObservatoryConfig(ServiceConfig):
def period_end_date(self):
return self._period_end_date
@property
def soft_limit(self):
return self._soft_limit
@property
def connection_str(self):
return self._connection_str
class ObservatorySnapshotConfig(DataObservatoryConfig):
SOFT_LIMIT_KEY = 'soft_obs_snapshot_limit'
QUOTA_KEY = 'obs_snapshot_quota'
PERIOD_END_DATE = 'period_end_date'
def __init__(self, redis_connection, db_conn, username, orgname=None):
super(ObservatorySnapshotConfig, self).__init__(redis_connection, db_conn,
username, orgname)
self._period_end_date = date_parse(self._redis_config[self.PERIOD_END_DATE])
if self.SOFT_LIMIT_KEY in self._redis_config and self._redis_config[self.SOFT_LIMIT_KEY].lower() == 'true':
self._soft_limit = True
else:
self._soft_limit = False
self._monthly_quota = 0
if self.QUOTA_KEY in self._redis_config:
self._monthly_quota = float(self._redis_config[self.QUOTA_KEY])
self._connection_str = self._db_config.data_observatory_connection_str
@property
def service_type(self):
return 'obs_snapshot'
class ObservatoryConfig(DataObservatoryConfig):
SOFT_LIMIT_KEY = 'soft_obs_general_limit'
QUOTA_KEY = 'obs_general_quota'
PERIOD_END_DATE = 'period_end_date'
def __init__(self, redis_connection, db_conn, username, orgname=None):
super(ObservatoryConfig, self).__init__(redis_connection, db_conn,
username, orgname)
self._period_end_date = date_parse(self._redis_config[self.PERIOD_END_DATE])
if self.SOFT_LIMIT_KEY in self._redis_config and self._redis_config[self.SOFT_LIMIT_KEY].lower() == 'true':
self._soft_limit = True
else:
self._soft_limit = False
self._monthly_quota = 0
if self.QUOTA_KEY in self._redis_config:
self._monthly_quota = float(self._redis_config[self.QUOTA_KEY])
self._connection_str = self._db_config.data_observatory_connection_str
@property
def service_type(self):
return 'obs_general'
class RoutingConfig(ServiceConfig):
@@ -200,28 +246,6 @@ class GeocoderConfig(ServiceConfig):
self.__parse_config(filtered_config, self._db_config)
self.__check_config(filtered_config)
def __get_user_config(self, username, orgname):
user_config = self._redis_connection.hgetall(
"rails:users:{0}".format(username))
if not user_config:
raise ConfigException("""There is no user config available. Please check your configuration.'""")
else:
if orgname:
self.__get_organization_config(orgname, user_config)
return user_config
def __get_organization_config(self, orgname, user_config):
org_config = self._redis_connection.hgetall(
"rails:orgs:{0}".format(orgname))
if not org_config:
raise ConfigException("""There is no organization config available. Please check your configuration.'""")
else:
user_config[self.QUOTA_KEY] = org_config[self.QUOTA_KEY]
user_config[self.PERIOD_END_DATE] = org_config[self.PERIOD_END_DATE]
user_config[self.GOOGLE_GEOCODER_CLIENT_ID] = org_config[self.GOOGLE_GEOCODER_CLIENT_ID]
user_config[self.GOOGLE_GEOCODER_API_KEY] = org_config[self.GOOGLE_GEOCODER_API_KEY]
def __check_config(self, filtered_config):
if filtered_config[self.GEOCODER_TYPE].lower() == self.NOKIA_GEOCODER:
if not set(self.NOKIA_GEOCODER_REDIS_MANDATORY_KEYS).issubset(set(filtered_config.keys())) or \
@@ -329,8 +353,10 @@ class GeocoderConfig(ServiceConfig):
class ServicesDBConfig:
def __init__(self, db_conn):
def __init__(self, db_conn, username, orgname):
self._db_conn = db_conn
self._username = username
self._orgname = orgname
return self._build()
def _build(self):
@@ -369,7 +395,12 @@ class ServicesDBConfig:
raise ConfigException('Data Observatory configuration missing')
else:
do_conf = json.loads(do_conf_json)
self._data_observatory_monthly_quota = do_conf['monthly_quota']
if self._orgname and self._orgname in do_conf['connection']['whitelist']:
self._data_observatory_connection_str = do_conf['connection']['staging']
elif self._username in do_conf['connection']['whitelist']:
self._data_observatory_connection_str = do_conf['connection']['staging']
else:
self._data_observatory_connection_str = do_conf['connection']['production']
def _get_logger_config(self):
logger_conf_json = self._get_conf('logger_conf')
@@ -428,8 +459,8 @@ class ServicesDBConfig:
return self._geocoder_log_path
@property
def data_observatory_monthly_quota(self):
return self._data_observatory_monthly_quota
def data_observatory_connection_str(self):
return self._data_observatory_connection_str
class ServicesRedisConfig:
@@ -438,24 +469,25 @@ class ServicesRedisConfig:
GOOGLE_GEOCODER_CLIENT_ID = 'google_maps_client_id'
QUOTA_KEY = 'geocoding_quota'
ISOLINES_QUOTA_KEY = 'here_isolines_quota'
OBS_SNAPSHOT_QUOTA_KEY = 'obs_snapshot_quota'
OBS_GENERAL_QUOTA_KEY = 'obs_general_quota'
PERIOD_END_DATE = 'period_end_date'
def __init__(self, redis_conn):
self._redis_connection = redis_conn
def build(self, username, password):
return self.__get_user_config(username, password)
def build(self, username, orgname):
return self.__get_user_config(username, orgname)
def __get_user_config(self, username, orgname):
user_config = self._redis_connection.hgetall(
"rails:users:{0}".format(username))
if not user_config:
raise ConfigException("""There is no user config available. Please check your configuration.'""")
else:
if orgname:
self.__get_organization_config(orgname, user_config)
elif orgname:
self.__get_organization_config(orgname, user_config)
return user_config
return user_config
def __get_organization_config(self, orgname, user_config):
org_config = self._redis_connection.hgetall(
@@ -465,6 +497,10 @@ class ServicesRedisConfig:
else:
user_config[self.QUOTA_KEY] = org_config[self.QUOTA_KEY]
user_config[self.ISOLINES_QUOTA_KEY] = org_config[self.ISOLINES_QUOTA_KEY]
if self.OBS_SNAPSHOT_QUOTA_KEY in org_config:
user_config[self.OBS_SNAPSHOT_QUOTA_KEY] = org_config[self.OBS_SNAPSHOT_QUOTA_KEY]
if self.OBS_GENERAL_QUOTA_KEY in org_config:
user_config[self.OBS_GENERAL_QUOTA_KEY] = org_config[self.OBS_GENERAL_QUOTA_KEY]
user_config[self.PERIOD_END_DATE] = org_config[self.PERIOD_END_DATE]
user_config[self.GOOGLE_GEOCODER_CLIENT_ID] = org_config[self.GOOGLE_GEOCODER_CLIENT_ID]
user_config[self.GOOGLE_GEOCODER_API_KEY] = org_config[self.GOOGLE_GEOCODER_API_KEY]

View File

@@ -73,7 +73,7 @@ class QuotaChecker:
elif re.match('routing_mapzen',
self._user_service_config.service_type) is not None:
return self.__check_routing_quota()
elif re.match('data_observatory',
elif re.match('obs_*',
self._user_service_config.service_type) is not None:
return self.__check_data_observatory_quota()
else:
@@ -120,11 +120,12 @@ class QuotaChecker:
def __check_data_observatory_quota(self):
user_quota = self._user_service_config.monthly_quota
soft_limit = self._user_service_config.soft_limit
today = date.today()
service_type = self._user_service_config.service_type
current_used = self._user_service.used_quota(service_type, today)
if (user_quota > 0 and current_used <= user_quota):
if soft_limit or (user_quota > 0 and current_used <= user_quota):
return True
else:
return False

View File

@@ -10,7 +10,7 @@ from setuptools import setup, find_packages
setup(
name='cartodb_services',
version='0.5.0',
version='0.6.2',
description='CartoDB Services API Python Library',

View File

@@ -1,5 +1,5 @@
import test_helper
from cartodb_services.metrics import GeocoderConfig, ConfigException
from cartodb_services.metrics import GeocoderConfig, ObservatorySnapshotConfig, ConfigException
from unittest import TestCase
from nose.tools import assert_raises
from mockredis import MockRedis
@@ -32,10 +32,29 @@ class TestConfig(TestCase):
assert geocoder_config.soft_geocoding_limit is False
assert geocoder_config.period_end_date.date() == yesterday.date()
def test_should_return_config_for_obs_snapshot(self):
yesterday = datetime.today() - timedelta(days=1)
test_helper.build_redis_user_config(self.redis_conn, 'test_user',
do_quota=100, soft_do_limit=True,
end_date=yesterday)
do_config = ObservatorySnapshotConfig(self.redis_conn, self.plpy_mock,
'test_user')
assert do_config.monthly_quota == 100
assert do_config.soft_limit is True
assert do_config.period_end_date.date() == yesterday.date()
def test_should_return_db_quota_if_not_redis_quota_config_obs_snapshot(self):
yesterday = datetime.today() - timedelta(days=1)
test_helper.build_redis_user_config(self.redis_conn, 'test_user',
end_date=yesterday)
do_config = ObservatorySnapshotConfig(self.redis_conn, self.plpy_mock,
'test_user')
assert do_config.monthly_quota == 0
assert do_config.soft_limit is False
assert do_config.period_end_date.date() == yesterday.date()
def test_should_raise_exception_when_missing_parameters(self):
plpy_mock = test_helper.build_plpy_mock(empty=True)
test_helper.build_redis_user_config(self.redis_conn, 'test_user')
assert_raises(ConfigException,
GeocoderConfig,
self.redis_conn, plpy_mock, 'test_user',
None)
assert_raises(ConfigException, GeocoderConfig, self.redis_conn,
plpy_mock, 'test_user', None)

View File

@@ -4,6 +4,8 @@ from mock import Mock
def build_redis_user_config(redis_conn, username, quota=100, soft_limit=False,
service="heremaps", isolines_quota=0,
do_quota=None, soft_do_limit=None,
do_general_quota=None, soft_do_general_limit=None,
end_date=datetime.today()):
user_redis_name = "rails:users:{0}".format(username)
redis_conn.hset(user_redis_name, 'soft_geocoding_limit', soft_limit)
@@ -11,23 +13,38 @@ def build_redis_user_config(redis_conn, username, quota=100, soft_limit=False,
redis_conn.hset(user_redis_name, 'here_isolines_quota', isolines_quota)
redis_conn.hset(user_redis_name, 'geocoder_type', service)
redis_conn.hset(user_redis_name, 'period_end_date', end_date)
if do_quota:
redis_conn.hset(user_redis_name, 'obs_snapshot_quota', do_quota)
if soft_do_limit:
redis_conn.hset(user_redis_name, 'soft_obs_snapshot_limit',
soft_do_limit)
if do_general_quota:
redis_conn.hset(user_redis_name, 'obs_general_quota', do_general_quota)
if soft_do_general_limit:
redis_conn.hset(user_redis_name, 'soft_obs_general_limit',
soft_do_general_limit)
redis_conn.hset(user_redis_name, 'google_maps_client_id', '')
redis_conn.hset(user_redis_name, 'google_maps_api_key', '')
def build_redis_org_config(redis_conn, orgname, quota=100, isolines_quota=0,
end_date=datetime.today()):
def build_redis_org_config(redis_conn, orgname, quota=100, service="heremaps",
isolines_quota=0, do_quota=None,
do_general_quota=None, end_date=datetime.today()):
org_redis_name = "rails:orgs:{0}".format(orgname)
redis_conn.hset(org_redis_name, 'geocoding_quota', quota)
redis_conn.hset(org_redis_name, 'here_isolines_quota', isolines_quota)
if do_quota:
redis_conn.hset(org_redis_name, 'obs_snapshot_quota', do_quota)
if do_general_quota:
redis_conn.hset(org_redis_name, 'obs_snapshot_quota', do_quota)
redis_conn.hset(org_redis_name, 'period_end_date', end_date)
redis_conn.hset(org_redis_name, 'google_maps_client_id', '')
redis_conn.hset(org_redis_name, 'google_maps_api_key', '')
def increment_geocoder_uses(redis_conn, username, orgname=None,
date=date.today(), service='geocoder_here',
metric='success_responses', amount=20):
def increment_service_uses(redis_conn, username, orgname=None,
date=date.today(), service='geocoder_here',
metric='success_responses', amount=20):
prefix = 'org' if orgname else 'user'
entity_name = orgname if orgname else username
yearmonth = date.strftime('%Y%m')
@@ -48,8 +65,8 @@ def _plpy_execute_side_effect(*args, **kwargs):
if args[0] == "SELECT cartodb.CDB_Conf_GetConf('heremaps_conf') as conf":
return [{'conf': '{"geocoder": {"app_id": "app_id", "app_code": "code", "geocoder_cost_per_hit": 1}, "isolines": {"app_id": "app_id", "app_code": "code"}}'}]
elif args[0] == "SELECT cartodb.CDB_Conf_GetConf('mapzen_conf') as conf":
return [{'conf': '{"routing": {"api_key": "valhalla-Z61FWEs", "monthly_quota": 1500000}, "geocoder": {"api_key": "search-d744tp0", "monthly_quota": 1500000}}'}]
return [{'conf': '{"routing": {"api_key": "api_key_rou", "monthly_quota": 1500000}, "geocoder": {"api_key": "api_key_geo", "monthly_quota": 1500000}}'}]
elif args[0] == "SELECT cartodb.CDB_Conf_GetConf('logger_conf') as conf":
return [{'conf': '{"geocoder_log_path": "/dev/null"}'}]
elif args[0] == "SELECT cartodb.CDB_Conf_GetConf('data_observatory_conf') as conf":
return [{'conf': '{"monthly_quota": 100000}'}]
return [{'conf': '{"connection": {"whitelist": ["ethervoid"], "production": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api", "staging": "host=localhost port=5432 dbname=dataservices_db user=geocoder_api"}}'}]

View File

@@ -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)

View File

@@ -1,7 +1,7 @@
import test_helper
from mockredis import MockRedis
from cartodb_services.metrics import QuotaService
from cartodb_services.metrics import GeocoderConfig, RoutingConfig, DataObservatoryConfig
from cartodb_services.metrics import GeocoderConfig, RoutingConfig, ObservatorySnapshotConfig
from unittest import TestCase
from nose.tools import assert_raises
from datetime import datetime, date
@@ -28,40 +28,40 @@ class TestQuotaService(TestCase):
def test_should_return_true_if_user_quota_is_not_completely_used(self):
qs = self.__build_geocoder_quota_service('test_user')
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user')
test_helper.increment_service_uses(self.redis_conn, 'test_user')
assert qs.check_user_quota() is True
def test_should_return_true_if_org_quota_is_not_completely_used(self):
qs = self.__build_geocoder_quota_service('test_user',
orgname='test_org')
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
orgname='test_org')
test_helper.increment_service_uses(self.redis_conn, 'test_user',
orgname='test_org')
assert qs.check_user_quota() is True
def test_should_return_false_if_user_quota_is_surpassed(self):
qs = self.__build_geocoder_quota_service('test_user')
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
amount=300)
test_helper.increment_service_uses(self.redis_conn, 'test_user',
amount=300)
assert qs.check_user_quota() is False
def test_should_return_false_if_org_quota_is_surpassed(self):
qs = self.__build_geocoder_quota_service('test_user',
orgname='test_org')
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
orgname='test_org', amount=400)
test_helper.increment_service_uses(self.redis_conn, 'test_user',
orgname='test_org', amount=400)
assert qs.check_user_quota() is False
def test_should_return_true_if_user_quota_is_surpassed_but_soft_limit_is_enabled(self):
qs = self.__build_geocoder_quota_service('test_user', soft_limit=True)
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
amount=300)
test_helper.increment_service_uses(self.redis_conn, 'test_user',
amount=300)
assert qs.check_user_quota() is True
def test_should_return_true_if_org_quota_is_surpassed_but_soft_limit_is_enabled(self):
qs = self.__build_geocoder_quota_service('test_user',
orgname='test_org',
soft_limit=True)
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
test_helper.increment_service_uses(self.redis_conn, 'test_user',
orgname='test_org', amount=400)
assert qs.check_user_quota() is True
@@ -109,29 +109,34 @@ class TestQuotaService(TestCase):
qs.increment_success_service_use(amount=1500000)
assert qs.check_user_quota() is False
def test_should_check_user_data_observatory_quota_correctly(self):
qs = self.__build_data_observatory_quota_service('test_user')
def test_should_check_user_obs_snapshot_quota_correctly(self):
qs = self.__build_obs_snapshot_quota_service('test_user')
qs.increment_success_service_use()
assert qs.check_user_quota() is True
qs.increment_success_service_use(amount=100000)
assert qs.check_user_quota() is False
def test_should_check_org_data_observatory_quota_correctly(self):
qs = self.__build_data_observatory_quota_service('test_user', orgname='testorg')
def test_should_check_org_obs_snapshot_quota_correctly(self):
qs = self.__build_obs_snapshot_quota_service('test_user',
orgname='testorg')
qs.increment_success_service_use()
assert qs.check_user_quota() is True
qs.increment_success_service_use(amount=100000)
assert qs.check_user_quota() is False
def __prepare_quota_service(self, username, quota, service, orgname,
soft_limit, end_date):
soft_limit, do_quota, soft_do_limit, end_date):
test_helper.build_redis_user_config(self.redis_conn, username,
quota=quota, service=service,
soft_limit=soft_limit,
soft_do_limit=soft_do_limit,
do_quota=do_quota,
end_date=end_date)
if orgname:
test_helper.build_redis_org_config(self.redis_conn, orgname,
quota=quota, end_date=end_date)
quota=quota, service=service,
do_quota=do_quota,
end_date=end_date)
self._plpy_mock = test_helper.build_plpy_mock()
def __build_geocoder_quota_service(self, username, quota=100,
@@ -139,27 +144,27 @@ class TestQuotaService(TestCase):
soft_limit=False,
end_date=datetime.today()):
self.__prepare_quota_service(username, quota, service, orgname,
soft_limit, end_date)
soft_limit, 0, False, end_date)
geocoder_config = GeocoderConfig(self.redis_conn, self._plpy_mock,
username, orgname)
return QuotaService(geocoder_config, redis_connection=self.redis_conn)
def __build_routing_quota_service(self, username, quota=100,
service='routing_mapzen', orgname=None,
soft_limit=False,
end_date=datetime.today()):
def __build_routing_quota_service(self, username, service='routing_mapzen',
orgname=None, soft_limit=False,
quota=100, end_date=datetime.today()):
self.__prepare_quota_service(username, quota, service, orgname,
soft_limit, end_date)
soft_limit, 0, False, end_date)
routing_config = RoutingConfig(self.redis_conn, self._plpy_mock,
username, orgname)
return QuotaService(routing_config, redis_connection=self.redis_conn)
def __build_data_observatory_quota_service(self, username, quota=100,
service='data_observatory', orgname=None,
def __build_obs_snapshot_quota_service(self, username, quota=100,
service='obs_snapshot',
orgname=None,
soft_limit=False,
end_date=datetime.today()):
self.__prepare_quota_service(username, quota, service, orgname,
soft_limit, end_date)
do_config = DataObservatoryConfig(self.redis_conn, self._plpy_mock,
self.__prepare_quota_service(username, 0, service, orgname, False,
quota, soft_limit, end_date)
do_config = ObservatorySnapshotConfig(self.redis_conn, self._plpy_mock,
username, orgname)
return QuotaService(do_config, redis_connection=self.redis_conn)

View File

@@ -18,15 +18,15 @@ class TestUserService(TestCase):
def test_user_used_quota_for_a_day(self):
us = self.__build_user_service('test_user')
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
amount=400)
test_helper.increment_service_uses(self.redis_conn, 'test_user',
amount=400)
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 400
def test_org_used_quota_for_a_day(self):
us = self.__build_user_service('test_user', orgname='test_org')
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
orgname='test_org',
amount=400)
test_helper.increment_service_uses(self.redis_conn, 'test_user',
orgname='test_org',
amount=400)
assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 400
def test_user_not_amount_in_used_quota_for_month_should_be_0(self):

File diff suppressed because one or more lines are too long

View File

@@ -32,3 +32,24 @@ class TestRoutingFunctions(TestCase):
IntegrationTestHelper.execute_query(self.sql_api_url, query)
except Exception as e:
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")