Merge pull request #351 from CartoDB/master
Merging back release artifacts from master to development
This commit is contained in:
commit
7e90529a00
8
NEWS.md
8
NEWS.md
@ -1,6 +1,6 @@
|
|||||||
March XX, 2017
|
March 8th, 2017
|
||||||
===================
|
===============
|
||||||
* Version XXXXXX of the server and version XXXXXX of the python library
|
* Version 0.22.0 of the server and version 0.14.0 of the python library
|
||||||
* New optional configuration parameters for external services can be provided through `cdb_conf`:
|
* New optional configuration parameters for external services can be provided through `cdb_conf`:
|
||||||
- In `heremaps_conf`, under `geocoder.service`: `json_url`, `connect_timeout`, `read_timeout`, `max_retries`, `gen`
|
- In `heremaps_conf`, under `geocoder.service`: `json_url`, `connect_timeout`, `read_timeout`, `max_retries`, `gen`
|
||||||
- In `heremaps_conf`, under `isolines.service`: `base_url`, `connect_timeout`, `read_timeout`, `max_retries`, `isoline_path`
|
- In `heremaps_conf`, under `isolines.service`: `base_url`, `connect_timeout`, `read_timeout`, `max_retries`, `isoline_path`
|
||||||
@ -8,6 +8,8 @@ March XX, 2017
|
|||||||
- In `mapzen_conf`, under `routing.service`: `base_url`, `connect_timeout`, `read_timeout`
|
- In `mapzen_conf`, under `routing.service`: `base_url`, `connect_timeout`, `read_timeout`
|
||||||
- In `mapzen_conf`, under `matrix.service`: `one_to_many_url`, `connect_timeout`, `read_timeout`
|
- In `mapzen_conf`, under `matrix.service`: `one_to_many_url`, `connect_timeout`, `read_timeout`
|
||||||
- In `mapzen_conf`, under `isochrones.service`: `base_url`, `connect_timeout`, `read_timeout`, `max_retries`
|
- In `mapzen_conf`, under `isochrones.service`: `base_url`, `connect_timeout`, `read_timeout`, `max_retries`
|
||||||
|
* Strictly speaking, version 0.14.0 of the python library is not compatible with 0.13.0, but the changes are made on method signatures with default values that were not used from the PG extension.
|
||||||
|
* Improvements to the Mapzen geocoder client, that should yield better results overall. See #342
|
||||||
|
|
||||||
February 2st, 2017
|
February 2st, 2017
|
||||||
===================
|
===================
|
||||||
|
@ -38,7 +38,7 @@ all: $(DATA)
|
|||||||
.PHONY: release
|
.PHONY: release
|
||||||
release: $(EXTENSION).control $(SOURCES_DATA)
|
release: $(EXTENSION).control $(SOURCES_DATA)
|
||||||
test -n "$(NEW_VERSION)" # $$NEW_VERSION VARIABLE MISSING. Eg. make release NEW_VERSION=0.x.0
|
test -n "$(NEW_VERSION)" # $$NEW_VERSION VARIABLE MISSING. Eg. make release NEW_VERSION=0.x.0
|
||||||
mv *.sql old_versions
|
git mv *.sql old_versions
|
||||||
$(SED) $(REPLACEMENTS) $(EXTENSION).control
|
$(SED) $(REPLACEMENTS) $(EXTENSION).control
|
||||||
cat $(SOURCES_DATA_DIR)/*.sql > $(EXTENSION)--$(NEW_VERSION).sql
|
cat $(SOURCES_DATA_DIR)/*.sql > $(EXTENSION)--$(NEW_VERSION).sql
|
||||||
$(ERB) version=$(NEW_VERSION) upgrade_downgrade_template.erb > $(EXTENSION)--$(EXTVERSION)--$(NEW_VERSION).sql
|
$(ERB) version=$(NEW_VERSION) upgrade_downgrade_template.erb > $(EXTENSION)--$(EXTVERSION)--$(NEW_VERSION).sql
|
||||||
|
292
server/extension/cdb_dataservices_server--0.21.0--0.22.0.sql
Normal file
292
server/extension/cdb_dataservices_server--0.21.0--0.22.0.sql
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
--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.22.0'" to load this file. \quit
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
from cartodb_services.tools import Logger,LoggerConfig
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||||
|
logger_config = GD["logger_config"]
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
|
||||||
|
quota_service = QuotaService(user_routing_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
raise Exception('You have reached the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = MapzenRouting(user_routing_config.mapzen_api_key, logger, user_routing_config.mapzen_service_params)
|
||||||
|
|
||||||
|
if not waypoints or len(waypoints) < 2:
|
||||||
|
logger.info("Empty origin or destination")
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return [None, None, None]
|
||||||
|
|
||||||
|
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:
|
||||||
|
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
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
logger.error('Error trying to calculate mapzen routing', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to calculate mapzen routing')
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu SECURITY DEFINER;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_here_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL)
|
||||||
|
RETURNS Geometry AS $$
|
||||||
|
from cartodb_services.here import HereMapsGeocoder
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
from cartodb_services.tools import Logger,LoggerConfig
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_geocoder_config = GD["user_geocoder_config_{0}".format(username)]
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||||
|
logger_config = GD["logger_config"]
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
# -- Check the quota
|
||||||
|
quota_service = QuotaService(user_geocoder_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
raise Exception('You have reached the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
geocoder = HereMapsGeocoder(user_geocoder_config.heremaps_app_id, user_geocoder_config.heremaps_app_code, logger, user_geocoder_config.heremaps_service_params)
|
||||||
|
coordinates = geocoder.geocode(searchtext=searchtext, city=city, state=state_province, country=country)
|
||||||
|
if coordinates:
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"])
|
||||||
|
point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0]
|
||||||
|
return point['st_setsrid']
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return None
|
||||||
|
except BaseException as e:
|
||||||
|
import sys
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
logger.error('Error trying to geocode street point using here maps', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to geocode street point using here maps')
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL)
|
||||||
|
RETURNS Geometry AS $$
|
||||||
|
import cartodb_services
|
||||||
|
cartodb_services.init(plpy, GD)
|
||||||
|
from cartodb_services.mapzen import MapzenGeocoder
|
||||||
|
from cartodb_services.mapzen.types import country_to_iso3
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
from cartodb_services.tools import Logger
|
||||||
|
from cartodb_services.refactor.tools.logger import LoggerConfigBuilder
|
||||||
|
from cartodb_services.refactor.service.mapzen_geocoder_config import MapzenGeocoderConfigBuilder
|
||||||
|
from cartodb_services.refactor.core.environment import ServerEnvironmentBuilder
|
||||||
|
from cartodb_services.refactor.backend.server_config import ServerConfigBackendFactory
|
||||||
|
from cartodb_services.refactor.backend.user_config import UserConfigBackendFactory
|
||||||
|
from cartodb_services.refactor.backend.org_config import OrgConfigBackendFactory
|
||||||
|
from cartodb_services.refactor.backend.redis_metrics_connection import RedisMetricsConnectionFactory
|
||||||
|
|
||||||
|
server_config_backend = ServerConfigBackendFactory().get()
|
||||||
|
environment = ServerEnvironmentBuilder(server_config_backend).get()
|
||||||
|
user_config_backend = UserConfigBackendFactory(username, environment, server_config_backend).get()
|
||||||
|
org_config_backend = OrgConfigBackendFactory(orgname, environment, server_config_backend).get()
|
||||||
|
|
||||||
|
logger_config = LoggerConfigBuilder(environment, server_config_backend).get()
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
|
||||||
|
mapzen_geocoder_config = MapzenGeocoderConfigBuilder(server_config_backend, user_config_backend, org_config_backend, username, orgname).get()
|
||||||
|
|
||||||
|
redis_metrics_connection = RedisMetricsConnectionFactory(environment, server_config_backend).get()
|
||||||
|
|
||||||
|
quota_service = QuotaService(mapzen_geocoder_config, redis_metrics_connection)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
raise Exception('You have reached the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
geocoder = MapzenGeocoder(mapzen_geocoder_config.mapzen_api_key, logger, mapzen_geocoder_config.service_params)
|
||||||
|
country_iso3 = None
|
||||||
|
if country:
|
||||||
|
country_iso3 = country_to_iso3(country)
|
||||||
|
coordinates = geocoder.geocode(searchtext=searchtext, city=city,
|
||||||
|
state_province=state_province,
|
||||||
|
country=country_iso3, search_type='address')
|
||||||
|
if coordinates:
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"])
|
||||||
|
point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0]
|
||||||
|
return point['st_setsrid']
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return None
|
||||||
|
except BaseException as e:
|
||||||
|
import sys
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
logger.error('Error trying to geocode street point using mapzen', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to geocode street point using mapzen')
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_isodistance(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
source geometry(Geometry, 4326),
|
||||||
|
mode TEXT,
|
||||||
|
data_range integer[],
|
||||||
|
options text[])
|
||||||
|
RETURNS SETOF cdb_dataservices_server.isoline AS $$
|
||||||
|
import json
|
||||||
|
from cartodb_services.mapzen import MatrixClient, MapzenIsolines
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
from cartodb_services.tools import Logger,LoggerConfig
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)]
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||||
|
logger_config = GD["logger_config"]
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
quota_service = QuotaService(user_isolines_routing_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
raise Exception('You have reached the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = MatrixClient(user_isolines_routing_config.mapzen_matrix_api_key, logger, user_isolines_routing_config.mapzen_matrix_service_params)
|
||||||
|
mapzen_isolines = MapzenIsolines(client, logger)
|
||||||
|
|
||||||
|
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']
|
||||||
|
origin = {'lat': lat, 'lon': lon}
|
||||||
|
else:
|
||||||
|
raise Exception('source is NULL')
|
||||||
|
|
||||||
|
# -- TODO Support options properly
|
||||||
|
isolines = {}
|
||||||
|
for r in data_range:
|
||||||
|
isoline = mapzen_isolines.calculate_isodistance(origin, mode, r)
|
||||||
|
isolines[r] = isoline
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for r in data_range:
|
||||||
|
|
||||||
|
if len(isolines[r]) >= 3:
|
||||||
|
# -- TODO encapsulate this block into a func/method
|
||||||
|
locations = isolines[r] + [ isolines[r][0] ] # close the polygon repeating the first point
|
||||||
|
wkt_coordinates = ','.join(["%f %f" % (l['lon'], l['lat']) for l in locations])
|
||||||
|
sql = "SELECT ST_MPolyFromText('MULTIPOLYGON((({0})))', 4326) as geom".format(wkt_coordinates)
|
||||||
|
multipolygon = plpy.execute(sql, 1)[0]['geom']
|
||||||
|
else:
|
||||||
|
multipolygon = None
|
||||||
|
|
||||||
|
result.append([source, r, multipolygon])
|
||||||
|
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
quota_service.increment_isolines_service_use(len(isolines))
|
||||||
|
return result
|
||||||
|
except BaseException as e:
|
||||||
|
import sys
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
logger.error('Error trying to get mapzen isolines', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to get mapzen isolines')
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu SECURITY DEFINER;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_isochrones(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
source geometry(Geometry, 4326),
|
||||||
|
mode TEXT,
|
||||||
|
data_range integer[],
|
||||||
|
options text[])
|
||||||
|
RETURNS SETOF cdb_dataservices_server.isoline AS $$
|
||||||
|
import json
|
||||||
|
from cartodb_services.mapzen import MatrixClient, MapzenIsochrones
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
from cartodb_services.tools import Logger,LoggerConfig
|
||||||
|
from cartodb_services.mapzen.types import coordinates_to_polygon
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)]
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||||
|
logger_config = GD["logger_config"]
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
# -- Check the quota
|
||||||
|
quota_service = QuotaService(user_isolines_routing_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
raise Exception('You have reached the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
mapzen_isochrones = MapzenIsochrones(user_isolines_routing_config.mapzen_matrix_api_key,
|
||||||
|
logger, user_isolines_routing_config.mapzen_isochrones_service_params)
|
||||||
|
|
||||||
|
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']
|
||||||
|
origin = {'lat': lat, 'lon': lon}
|
||||||
|
else:
|
||||||
|
raise Exception('source is NULL')
|
||||||
|
|
||||||
|
resp = mapzen_isochrones.isochrone(origin, mode, data_range)
|
||||||
|
|
||||||
|
if resp:
|
||||||
|
result = []
|
||||||
|
for isochrone in resp:
|
||||||
|
result_polygon = coordinates_to_polygon(isochrone.coordinates)
|
||||||
|
if result_polygon:
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
result.append([source, isochrone.duration, result_polygon])
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
result.append([source, isochrone.duration, None])
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
quota_service.increment_isolines_service_use(len(result))
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return []
|
||||||
|
except BaseException as e:
|
||||||
|
import sys
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
logger.error('Error trying to get mapzen isochrones', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to get mapzen isochrones')
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu SECURITY DEFINER;
|
292
server/extension/cdb_dataservices_server--0.22.0--0.21.0.sql
Normal file
292
server/extension/cdb_dataservices_server--0.22.0--0.21.0.sql
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
--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.21.0'" to load this file. \quit
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
from cartodb_services.tools import Logger,LoggerConfig
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||||
|
logger_config = GD["logger_config"]
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
|
||||||
|
quota_service = QuotaService(user_routing_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
raise Exception('You have reached the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = MapzenRouting(user_routing_config.mapzen_api_key, logger)
|
||||||
|
|
||||||
|
if not waypoints or len(waypoints) < 2:
|
||||||
|
logger.info("Empty origin or destination")
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return [None, None, None]
|
||||||
|
|
||||||
|
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:
|
||||||
|
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
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
logger.error('Error trying to calculate mapzen routing', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to calculate mapzen routing')
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu SECURITY DEFINER;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_here_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL)
|
||||||
|
RETURNS Geometry AS $$
|
||||||
|
from cartodb_services.here import HereMapsGeocoder
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
from cartodb_services.tools import Logger,LoggerConfig
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_geocoder_config = GD["user_geocoder_config_{0}".format(username)]
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||||
|
logger_config = GD["logger_config"]
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
# -- Check the quota
|
||||||
|
quota_service = QuotaService(user_geocoder_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
raise Exception('You have reached the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
geocoder = HereMapsGeocoder(user_geocoder_config.heremaps_app_id, user_geocoder_config.heremaps_app_code, logger)
|
||||||
|
coordinates = geocoder.geocode(searchtext=searchtext, city=city, state=state_province, country=country)
|
||||||
|
if coordinates:
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"])
|
||||||
|
point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0]
|
||||||
|
return point['st_setsrid']
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return None
|
||||||
|
except BaseException as e:
|
||||||
|
import sys
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
logger.error('Error trying to geocode street point using here maps', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to geocode street point using here maps')
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL)
|
||||||
|
RETURNS Geometry AS $$
|
||||||
|
import cartodb_services
|
||||||
|
cartodb_services.init(plpy, GD)
|
||||||
|
from cartodb_services.mapzen import MapzenGeocoder
|
||||||
|
from cartodb_services.mapzen.types import country_to_iso3
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
from cartodb_services.tools import Logger
|
||||||
|
from cartodb_services.refactor.tools.logger import LoggerConfigBuilder
|
||||||
|
from cartodb_services.refactor.service.mapzen_geocoder_config import MapzenGeocoderConfigBuilder
|
||||||
|
from cartodb_services.refactor.core.environment import ServerEnvironmentBuilder
|
||||||
|
from cartodb_services.refactor.backend.server_config import ServerConfigBackendFactory
|
||||||
|
from cartodb_services.refactor.backend.user_config import UserConfigBackendFactory
|
||||||
|
from cartodb_services.refactor.backend.org_config import OrgConfigBackendFactory
|
||||||
|
from cartodb_services.refactor.backend.redis_metrics_connection import RedisMetricsConnectionFactory
|
||||||
|
|
||||||
|
server_config_backend = ServerConfigBackendFactory().get()
|
||||||
|
environment = ServerEnvironmentBuilder(server_config_backend).get()
|
||||||
|
user_config_backend = UserConfigBackendFactory(username, environment, server_config_backend).get()
|
||||||
|
org_config_backend = OrgConfigBackendFactory(orgname, environment, server_config_backend).get()
|
||||||
|
|
||||||
|
logger_config = LoggerConfigBuilder(environment, server_config_backend).get()
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
|
||||||
|
mapzen_geocoder_config = MapzenGeocoderConfigBuilder(server_config_backend, user_config_backend, org_config_backend, username, orgname).get()
|
||||||
|
|
||||||
|
redis_metrics_connection = RedisMetricsConnectionFactory(environment, server_config_backend).get()
|
||||||
|
|
||||||
|
quota_service = QuotaService(mapzen_geocoder_config, redis_metrics_connection)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
raise Exception('You have reached the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
geocoder = MapzenGeocoder(mapzen_geocoder_config.mapzen_api_key, logger)
|
||||||
|
country_iso3 = None
|
||||||
|
if country:
|
||||||
|
country_iso3 = country_to_iso3(country)
|
||||||
|
coordinates = geocoder.geocode(searchtext=searchtext, city=city,
|
||||||
|
state_province=state_province,
|
||||||
|
country=country_iso3, search_type='address')
|
||||||
|
if coordinates:
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"])
|
||||||
|
point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0]
|
||||||
|
return point['st_setsrid']
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return None
|
||||||
|
except BaseException as e:
|
||||||
|
import sys
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
logger.error('Error trying to geocode street point using mapzen', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to geocode street point using mapzen')
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_isodistance(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
source geometry(Geometry, 4326),
|
||||||
|
mode TEXT,
|
||||||
|
data_range integer[],
|
||||||
|
options text[])
|
||||||
|
RETURNS SETOF cdb_dataservices_server.isoline AS $$
|
||||||
|
import json
|
||||||
|
from cartodb_services.mapzen import MatrixClient, MapzenIsolines
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
from cartodb_services.tools import Logger,LoggerConfig
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)]
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||||
|
logger_config = GD["logger_config"]
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
quota_service = QuotaService(user_isolines_routing_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
raise Exception('You have reached the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = MatrixClient(user_isolines_routing_config.mapzen_matrix_api_key, logger)
|
||||||
|
mapzen_isolines = MapzenIsolines(client, logger)
|
||||||
|
|
||||||
|
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']
|
||||||
|
origin = {'lat': lat, 'lon': lon}
|
||||||
|
else:
|
||||||
|
raise Exception('source is NULL')
|
||||||
|
|
||||||
|
# -- TODO Support options properly
|
||||||
|
isolines = {}
|
||||||
|
for r in data_range:
|
||||||
|
isoline = mapzen_isolines.calculate_isodistance(origin, mode, r)
|
||||||
|
isolines[r] = isoline
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for r in data_range:
|
||||||
|
|
||||||
|
if len(isolines[r]) >= 3:
|
||||||
|
# -- TODO encapsulate this block into a func/method
|
||||||
|
locations = isolines[r] + [ isolines[r][0] ] # close the polygon repeating the first point
|
||||||
|
wkt_coordinates = ','.join(["%f %f" % (l['lon'], l['lat']) for l in locations])
|
||||||
|
sql = "SELECT ST_MPolyFromText('MULTIPOLYGON((({0})))', 4326) as geom".format(wkt_coordinates)
|
||||||
|
multipolygon = plpy.execute(sql, 1)[0]['geom']
|
||||||
|
else:
|
||||||
|
multipolygon = None
|
||||||
|
|
||||||
|
result.append([source, r, multipolygon])
|
||||||
|
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
quota_service.increment_isolines_service_use(len(isolines))
|
||||||
|
return result
|
||||||
|
except BaseException as e:
|
||||||
|
import sys
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
logger.error('Error trying to get mapzen isolines', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to get mapzen isolines')
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu SECURITY DEFINER;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_isochrones(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
source geometry(Geometry, 4326),
|
||||||
|
mode TEXT,
|
||||||
|
data_range integer[],
|
||||||
|
options text[])
|
||||||
|
RETURNS SETOF cdb_dataservices_server.isoline AS $$
|
||||||
|
import json
|
||||||
|
from cartodb_services.mapzen import MatrixClient, MapzenIsochrones
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
from cartodb_services.tools import Logger,LoggerConfig
|
||||||
|
from cartodb_services.mapzen.types import coordinates_to_polygon
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)]
|
||||||
|
|
||||||
|
plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
|
||||||
|
logger_config = GD["logger_config"]
|
||||||
|
logger = Logger(logger_config)
|
||||||
|
# -- Check the quota
|
||||||
|
quota_service = QuotaService(user_isolines_routing_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
raise Exception('You have reached the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
mapzen_isochrones = MapzenIsochrones(user_isolines_routing_config.mapzen_matrix_api_key,
|
||||||
|
logger)
|
||||||
|
|
||||||
|
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']
|
||||||
|
origin = {'lat': lat, 'lon': lon}
|
||||||
|
else:
|
||||||
|
raise Exception('source is NULL')
|
||||||
|
|
||||||
|
resp = mapzen_isochrones.isochrone(origin, mode, data_range)
|
||||||
|
|
||||||
|
if resp:
|
||||||
|
result = []
|
||||||
|
for isochrone in resp:
|
||||||
|
result_polygon = coordinates_to_polygon(isochrone.coordinates)
|
||||||
|
if result_polygon:
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
result.append([source, isochrone.duration, result_polygon])
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
result.append([source, isochrone.duration, None])
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
quota_service.increment_isolines_service_use(len(result))
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return []
|
||||||
|
except BaseException as e:
|
||||||
|
import sys
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
logger.error('Error trying to get mapzen isochrones', sys.exc_info(), data={"username": username, "orgname": orgname})
|
||||||
|
raise Exception('Error trying to get mapzen isochrones')
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu SECURITY DEFINER;
|
2900
server/extension/cdb_dataservices_server--0.22.0.sql
Normal file
2900
server/extension/cdb_dataservices_server--0.22.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
comment = 'CartoDB dataservices server extension'
|
comment = 'CartoDB dataservices server extension'
|
||||||
default_version = '0.21.0'
|
default_version = '0.22.0'
|
||||||
requires = 'plpythonu, plproxy, postgis, cdb_geocoder'
|
requires = 'plpythonu, plproxy, postgis, cdb_geocoder'
|
||||||
superuser = true
|
superuser = true
|
||||||
schema = cdb_dataservices_server
|
schema = cdb_dataservices_server
|
||||||
|
@ -10,7 +10,7 @@ from setuptools import setup, find_packages
|
|||||||
setup(
|
setup(
|
||||||
name='cartodb_services',
|
name='cartodb_services',
|
||||||
|
|
||||||
version='0.13.0',
|
version='0.14.0',
|
||||||
|
|
||||||
description='CartoDB Services API Python Library',
|
description='CartoDB Services API Python Library',
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user