Compare commits

..

23 Commits

Author SHA1 Message Date
Juan Ignacio Sánchez Lara
07ed2a4112 Merge pull request #471 from CartoDB/1333-Mapbox_isolines_almost_shoreline
Fix Mapbox isolines near the shoreline
2018-03-05 16:14:45 +01:00
Antonio
35f743164e Keep deleting points that got None 2018-03-02 10:27:37 +01:00
Antonio
4308b5f351 Remove too far away points (filtering by time) 2018-03-02 10:23:58 +01:00
Antonio
9fb04fdc24 Version bumped 2018-02-28 11:49:23 +01:00
Antonio
a2fd0bf142 Merge branch 'master' into 1333-Mapbox_isolines_almost_shoreline 2018-02-28 11:48:00 +01:00
Antonio Carlón
6534b12606 Merge pull request #473 from CartoDB/development
Version 0.17.1 of the python library
2018-02-28 11:37:52 +01:00
Antonio Carlón
8d9c3a4bf7 Merge pull request #472 from CartoDB/fix_mapzen_routing
Fix mapzen routing bug
2018-02-28 11:35:26 +01:00
Mario de Frutos
ad46de1156 Bump version and update NEWS.md 2018-02-27 18:11:50 +01:00
Mario de Frutos
97f1611d62 Only get mapzen/mapbox values in case the provider of routing is one of these 2018-02-27 18:09:21 +01:00
Antonio
bc4c9fea33 Using Mapbox returned destinations as coordinates for isolines 2018-02-26 12:45:08 +01:00
Antonio Carlón
e110ab4cc3 Merge pull request #469 from CartoDB/development
Release 0.17.0
2018-02-22 12:46:34 +01:00
Antonio Carlón
e646000f24 Merge pull request #468 from CartoDB/remove_legacy_mapzen
Remove legacy mapzen
2018-02-22 12:41:48 +01:00
Mario de Frutos
05e2cc981e Change min log level for tests to WARNING 2018-02-22 11:20:16 +01:00
Mario de Frutos
cbc19b869c Fix CR suggestions 2018-02-22 11:14:33 +01:00
Mario de Frutos
199788748b Updated NEWS.md 2018-02-21 19:14:56 +01:00
Mario de Frutos
e3f23adfdd Bump to version 0.17.0 2018-02-21 19:14:47 +01:00
Mario de Frutos
39dabffb85 Now is not mandatory to have mapzen configuration becuase its deprecated as provider 2018-02-21 19:14:29 +01:00
Mario de Frutos
03e1d1ca61 Change default provider to mapbox instead of mapzen 2018-02-21 19:13:59 +01:00
Mario de Frutos
c14fb057d3 Update README.md 2018-02-14 11:03:51 +01:00
Mario de Frutos
9e247685b8 Merge pull request #465 from CartoDB/457-Fix_Mapbox_Python_tests
457 fix mapbox python tests
2018-02-14 10:21:29 +01:00
Juan Ignacio Sánchez Lara
1fdb4d3b3a Pythonic refactor, importing single method 2018-02-13 18:24:21 +01:00
Juan Ignacio Sánchez Lara
029541f298 api_key -> mapbox_api_key rename refactor 2018-02-13 16:16:13 +01:00
Juan Ignacio Sánchez Lara
45d9edbba6 Mapbox test API key is supplied now through a MAPBOX_API_KEY environment variable 2018-02-13 15:58:10 +01:00
15 changed files with 105 additions and 60 deletions

16
NEWS.md
View File

@@ -1,4 +1,20 @@
February 22th, 2018
==================
* Version `0.17.2` of the python library
* Fix bug with Mapbox isolines not stopping at the seacoast
February 27th, 2018
==================
* Version `0.17.1` of the python library
* Fix bug when the mapzen credentials are not in the db config and we keep getting them
February 22th, 2018
==================
* Version `0.17.0` of the python library
* Change default provider to Mapbox
* Remove the obligatory nature of the Mapzen configuration due to its deprecation as provider
February 13th, 2018
==================
* Version `0.16.7` of the python library

View File

@@ -1,3 +1,5 @@
-- Only show warning or error messages in the tests output
SET client_min_messages TO WARNING;
-- Install dependencies
CREATE EXTENSION postgis;
CREATE EXTENSION plpythonu;

View File

@@ -1,3 +1,5 @@
-- Only show warning or error messages in the tests output
SET client_min_messages TO WARNING;
-- Install dependencies
CREATE EXTENSION postgis;
CREATE EXTENSION plpythonu;

View File

@@ -1,3 +1,5 @@
-- Only show warning or error messages in the tests output
SET client_min_messages TO WARNING;
-- Install dependencies
CREATE EXTENSION postgis;
CREATE EXTENSION plpythonu;

View File

@@ -1,3 +1,5 @@
-- Only show warning or error messages in the tests output
SET client_min_messages TO WARNING;
-- Install dependencies
CREATE EXTENSION postgis;
CREATE EXTENSION plpythonu;

View File

@@ -24,7 +24,7 @@ NOTE: a system installation is required at present because the library is meant
## Running the unit tests
Just run `nosetests test/`
Just run `MAPBOX_API_KEY=xxx nosetests test/`
```shell
$ nosetests test/
......................................................................................................

View File

@@ -4,6 +4,7 @@ Uses the Mapbox Time Matrix service.
'''
import json
from cartodb_services.tools import Coordinate
from cartodb_services.tools.spherical import (get_angles,
calculate_dest_location)
from cartodb_services.mapbox.matrix_client import (validate_profile,
@@ -11,7 +12,9 @@ from cartodb_services.mapbox.matrix_client import (validate_profile,
PROFILE_WALKING,
PROFILE_DRIVING,
PROFILE_CYCLING,
ENTRY_DURATIONS)
ENTRY_DURATIONS,
ENTRY_DESTINATIONS,
ENTRY_LOCATION)
MAX_SPEEDS = {
PROFILE_WALKING: 3.3333333, # In m/s, assuming 12km/h walking speed
@@ -53,6 +56,7 @@ class MapboxIsolines():
return []
costs = [None] * number_of_angles
destinations = [None] * number_of_angles
for idx, cost in enumerate(json_response[ENTRY_DURATIONS][0][1:]):
if cost:
@@ -60,7 +64,11 @@ class MapboxIsolines():
else:
costs[idx] = isorange
return costs
for idx, destination in enumerate(json_response[ENTRY_DESTINATIONS][1:]):
destinations[idx] = Coordinate(destination[ENTRY_LOCATION][0],
destination[ENTRY_LOCATION][1])
return costs, destinations
def calculate_isochrone(self, origin, time_ranges,
profile=DEFAULT_PROFILE):
@@ -122,10 +130,12 @@ class MapboxIsolines():
# NOTE: sometimes it cannot calculate the cost and returns None.
# Just assume isorange and stop the calculations there
costs = cost_method(origin=origin, targets=location_estimates,
isorange=isorange, profile=profile,
unit_factor=unit_factor,
number_of_angles=number_of_angles)
costs, destinations = cost_method(origin=origin,
targets=location_estimates,
isorange=isorange,
profile=profile,
unit_factor=unit_factor,
number_of_angles=number_of_angles)
if not costs:
continue
@@ -152,8 +162,8 @@ class MapboxIsolines():
# delete points that got None
location_estimates_filtered = []
for i, c in enumerate(costs):
if c != isorange:
location_estimates_filtered.append(location_estimates[i])
if c != isorange and c < isorange * (1 + tolerance):
location_estimates_filtered.append(destinations[i])
return location_estimates_filtered

View File

@@ -30,6 +30,8 @@ VALID_PROFILES = [PROFILE_DRIVING_TRAFFIC,
PROFILE_WALKING]
ENTRY_DURATIONS = 'durations'
ENTRY_DESTINATIONS = 'destinations'
ENTRY_LOCATION = 'location'
def validate_profile(profile):

View File

@@ -136,7 +136,7 @@ class RoutingConfig(ServiceConfig):
ROUTING_PROVIDER_KEY = 'routing_provider'
MAPZEN_PROVIDER = 'mapzen'
MAPBOX_PROVIDER = 'mapbox'
DEFAULT_PROVIDER = MAPZEN_PROVIDER
DEFAULT_PROVIDER = MAPBOX_PROVIDER
QUOTA_KEY = 'mapzen_routing_quota'
SOFT_LIMIT_KEY = 'soft_mapzen_routing_limit'
METRICS_LOG_KEY = 'routing_log_path'
@@ -147,10 +147,12 @@ class RoutingConfig(ServiceConfig):
self._routing_provider = self._redis_config[self.ROUTING_PROVIDER_KEY]
if not self._routing_provider:
self._routing_provider = self.DEFAULT_PROVIDER
self._mapzen_api_key = self._db_config.mapzen_routing_api_key
self._mapzen_service_params = self._db_config.mapzen_routing_service_params
self._mapbox_api_keys = self._db_config.mapbox_routing_api_keys
self._mapbox_service_params = self._db_config.mapbox_routing_service_params
if self._routing_provider == self.MAPZEN_PROVIDER:
self._mapzen_api_key = self._db_config.mapzen_routing_api_key
self._mapzen_service_params = self._db_config.mapzen_routing_service_params
elif self._routing_provider == self.MAPBOX_PROVIDER:
self._mapbox_api_keys = self._db_config.mapbox_routing_api_keys
self._mapbox_service_params = self._db_config.mapbox_routing_service_params
self._set_monthly_quota()
self._set_soft_limit()
self._period_end_date = date_parse(self._redis_config[self.PERIOD_END_DATE])
@@ -226,7 +228,7 @@ class IsolinesRoutingConfig(ServiceConfig):
MAPZEN_PROVIDER = 'mapzen'
MAPBOX_PROVIDER = 'mapbox'
HEREMAPS_PROVIDER = 'heremaps'
DEFAULT_PROVIDER = MAPZEN_PROVIDER
DEFAULT_PROVIDER = MAPBOX_PROVIDER
METRICS_LOG_KEY = 'isolines_log_path'
def __init__(self, redis_connection, db_conn, username, orgname=None):
@@ -391,7 +393,7 @@ class GeocoderConfig(ServiceConfig):
USERNAME_KEY = 'username'
ORGNAME_KEY = 'orgname'
PERIOD_END_DATE = 'period_end_date'
DEFAULT_PROVIDER = MAPZEN_GEOCODER
DEFAULT_PROVIDER = MAPBOX_GEOCODER
METRICS_LOG_KEY = 'geocoder_log_path'
def __init__(self, redis_connection, db_conn, username, orgname=None, forced_provider=None):
@@ -576,50 +578,51 @@ class ServicesDBConfig:
heremaps_conf_json = self._get_conf('heremaps_conf')
if not heremaps_conf_json:
raise ConfigException('Here maps configuration missing')
else:
heremaps_conf = json.loads(heremaps_conf_json)
self._heremaps_geocoder_app_id = heremaps_conf['geocoder']['app_id']
self._heremaps_geocoder_app_code = heremaps_conf['geocoder']['app_code']
self._heremaps_geocoder_cost_per_hit = heremaps_conf['geocoder'][
'geocoder_cost_per_hit']
self._heremaps_geocoder_service_params = heremaps_conf['geocoder'].get('service', {})
self._heremaps_isolines_app_id = heremaps_conf['isolines']['app_id']
self._heremaps_isolines_app_code = heremaps_conf['isolines']['app_code']
self._heremaps_isolines_service_params = heremaps_conf['isolines'].get('service', {})
heremaps_conf = json.loads(heremaps_conf_json)
self._heremaps_geocoder_app_id = heremaps_conf['geocoder']['app_id']
self._heremaps_geocoder_app_code = heremaps_conf['geocoder']['app_code']
self._heremaps_geocoder_cost_per_hit = heremaps_conf['geocoder'][
'geocoder_cost_per_hit']
self._heremaps_geocoder_service_params = heremaps_conf['geocoder'].get('service', {})
self._heremaps_isolines_app_id = heremaps_conf['isolines']['app_id']
self._heremaps_isolines_app_code = heremaps_conf['isolines']['app_code']
self._heremaps_isolines_service_params = heremaps_conf['isolines'].get('service', {})
def _get_mapzen_config(self):
mapzen_conf_json = self._get_conf('mapzen_conf')
# We dont use mapzen anymore so we don't need to check for its configuration
if not mapzen_conf_json:
raise ConfigException('Mapzen configuration missing')
else:
mapzen_conf = json.loads(mapzen_conf_json)
self._mapzen_matrix_api_key = mapzen_conf['matrix']['api_key']
self._mapzen_matrix_quota = mapzen_conf['matrix']['monthly_quota']
self._mapzen_matrix_service_params = mapzen_conf['matrix'].get('service', {})
self._mapzen_isochrones_service_params = mapzen_conf.get('isochrones', {}).get('service', {})
self._mapzen_routing_api_key = mapzen_conf['routing']['api_key']
self._mapzen_routing_quota = mapzen_conf['routing']['monthly_quota']
self._mapzen_routing_service_params = mapzen_conf['routing'].get('service', {})
self._mapzen_geocoder_api_key = mapzen_conf['geocoder']['api_key']
self._mapzen_geocoder_quota = mapzen_conf['geocoder']['monthly_quota']
self._mapzen_geocoder_service_params = mapzen_conf['geocoder'].get('service', {})
return
mapzen_conf = json.loads(mapzen_conf_json)
self._mapzen_matrix_api_key = mapzen_conf['matrix']['api_key']
self._mapzen_matrix_quota = mapzen_conf['matrix']['monthly_quota']
self._mapzen_matrix_service_params = mapzen_conf['matrix'].get('service', {})
self._mapzen_isochrones_service_params = mapzen_conf.get('isochrones', {}).get('service', {})
self._mapzen_routing_api_key = mapzen_conf['routing']['api_key']
self._mapzen_routing_quota = mapzen_conf['routing']['monthly_quota']
self._mapzen_routing_service_params = mapzen_conf['routing'].get('service', {})
self._mapzen_geocoder_api_key = mapzen_conf['geocoder']['api_key']
self._mapzen_geocoder_quota = mapzen_conf['geocoder']['monthly_quota']
self._mapzen_geocoder_service_params = mapzen_conf['geocoder'].get('service', {})
def _get_mapbox_config(self):
mapbox_conf_json = self._get_conf('mapbox_conf')
if not mapbox_conf_json:
raise ConfigException('Mapbox configuration missing')
else:
mapbox_conf = json.loads(mapbox_conf_json)
self._mapbox_matrix_api_keys = mapbox_conf['matrix']['api_keys']
self._mapbox_matrix_quota = mapbox_conf['matrix']['monthly_quota']
self._mapbox_matrix_service_params = mapbox_conf['matrix'].get('service', {})
self._mapbox_isochrones_service_params = mapbox_conf.get('isochrones', {}).get('service', {})
self._mapbox_routing_api_keys = mapbox_conf['routing']['api_keys']
self._mapbox_routing_quota = mapbox_conf['routing']['monthly_quota']
self._mapbox_routing_service_params = mapbox_conf['routing'].get('service', {})
self._mapbox_geocoder_api_keys = mapbox_conf['geocoder']['api_keys']
self._mapbox_geocoder_quota = mapbox_conf['geocoder']['monthly_quota']
self._mapbox_geocoder_service_params = mapbox_conf['geocoder'].get('service', {})
mapbox_conf = json.loads(mapbox_conf_json)
self._mapbox_matrix_api_keys = mapbox_conf['matrix']['api_keys']
self._mapbox_matrix_quota = mapbox_conf['matrix']['monthly_quota']
self._mapbox_matrix_service_params = mapbox_conf['matrix'].get('service', {})
self._mapbox_isochrones_service_params = mapbox_conf.get('isochrones', {}).get('service', {})
self._mapbox_routing_api_keys = mapbox_conf['routing']['api_keys']
self._mapbox_routing_quota = mapbox_conf['routing']['monthly_quota']
self._mapbox_routing_service_params = mapbox_conf['routing'].get('service', {})
self._mapbox_geocoder_api_keys = mapbox_conf['geocoder']['api_keys']
self._mapbox_geocoder_quota = mapbox_conf['geocoder']['monthly_quota']
self._mapbox_geocoder_service_params = mapbox_conf['geocoder'].get('service', {})
def _get_data_observatory_config(self):
do_conf_json = self._get_conf('data_observatory_conf')

View File

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

View File

@@ -0,0 +1,6 @@
import os
def mapbox_api_key():
"""Returns Mapbox API key. Requires setting MAPBOX_API_KEY environment variable."""
return os.environ['MAPBOX_API_KEY']

View File

@@ -2,8 +2,8 @@ import unittest
from mock import Mock
from cartodb_services.mapbox import MapboxGeocoder
from cartodb_services.tools.exceptions import ServiceException
from credentials import mapbox_api_key
VALID_TOKEN = 'pk.eyJ1IjoiYWNhcmxvbiIsImEiOiJjamJuZjQ1Zjc0Ymt4Mnh0YmFrMmhtYnY4In0.gt9cw0VeKc3rM2mV5pcEmg'
INVALID_TOKEN = 'invalid_token'
VALID_ADDRESS = 'Calle Siempreviva 3, Valladolid'
WELL_KNOWN_LONGITUDE = -4.730947
@@ -12,7 +12,7 @@ WELL_KNOWN_LATITUDE = 41.668654
class MapboxGeocoderTestCase(unittest.TestCase):
def setUp(self):
self.geocoder = MapboxGeocoder(token=VALID_TOKEN, logger=Mock())
self.geocoder = MapboxGeocoder(token=mapbox_api_key(), logger=Mock())
def test_invalid_token(self):
invalid_geocoder = MapboxGeocoder(token=INVALID_TOKEN, logger=Mock())

View File

@@ -7,15 +7,15 @@ from cartodb_services.mapbox.routing import MapboxRouting
from cartodb_services.tools import Coordinate
from cartodb_services.tools.coordinates import (validate_coordinates,
marshall_coordinates)
from credentials import mapbox_api_key
VALID_TOKEN = 'pk.eyJ1IjoiYWNhcmxvbiIsImEiOiJjamJuZjQ1Zjc0Ymt4Mnh0YmFrMmhtYnY4In0.gt9cw0VeKc3rM2mV5pcEmg'
VALID_ORIGIN = Coordinate(-73.989, 40.733)
class MapboxIsolinesTestCase(unittest.TestCase):
def setUp(self):
matrix_client = MapboxMatrixClient(token=VALID_TOKEN, logger=Mock())
matrix_client = MapboxMatrixClient(token=mapbox_api_key(), logger=Mock())
self.mapbox_isolines = MapboxIsolines(matrix_client, logger=Mock())
def test_calculate_isochrone(self):

View File

@@ -4,8 +4,8 @@ from cartodb_services.mapbox import MapboxMatrixClient
from cartodb_services.mapbox.matrix_client import DEFAULT_PROFILE
from cartodb_services.tools.exceptions import ServiceException
from cartodb_services.tools import Coordinate
from credentials import mapbox_api_key
VALID_TOKEN = 'pk.eyJ1IjoiYWNhcmxvbiIsImEiOiJjamJuZjQ1Zjc0Ymt4Mnh0YmFrMmhtYnY4In0.gt9cw0VeKc3rM2mV5pcEmg'
INVALID_TOKEN = 'invalid_token'
VALID_ORIGIN = Coordinate(-73.989, 40.733)
VALID_TARGET = Coordinate(-74, 40.733)
@@ -22,7 +22,7 @@ INVALID_PROFILE = 'invalid_profile'
class MapboxMatrixTestCase(unittest.TestCase):
def setUp(self):
self.matrix_client = MapboxMatrixClient(token=VALID_TOKEN,
self.matrix_client = MapboxMatrixClient(token=mapbox_api_key(),
logger=Mock())
def test_invalid_profile(self):

View File

@@ -4,8 +4,8 @@ from cartodb_services.mapbox import MapboxRouting
from cartodb_services.mapbox.routing import DEFAULT_PROFILE
from cartodb_services.tools.exceptions import ServiceException
from cartodb_services.tools import Coordinate
from credentials import mapbox_api_key
VALID_TOKEN = 'pk.eyJ1IjoiYWNhcmxvbiIsImEiOiJjamJuZjQ1Zjc0Ymt4Mnh0YmFrMmhtYnY4In0.gt9cw0VeKc3rM2mV5pcEmg'
INVALID_TOKEN = 'invalid_token'
VALID_WAYPOINTS = [Coordinate(-73.989, 40.733), Coordinate(-74, 40.733)]
NUM_WAYPOINTS_MAX = 25
@@ -31,7 +31,7 @@ WELL_KNOWN_LENGTH = 1317.9
class MapboxRoutingTestCase(unittest.TestCase):
def setUp(self):
self.routing = MapboxRouting(token=VALID_TOKEN, logger=Mock())
self.routing = MapboxRouting(token=mapbox_api_key(), logger=Mock())
def test_invalid_profile(self):
with self.assertRaises(ValueError):