Google geocoder working

This commit is contained in:
Mario de Frutos
2016-01-27 19:04:27 +01:00
parent 731eb8c74f
commit e7c58b9a51
39 changed files with 2349 additions and 34 deletions

View File

@@ -32,19 +32,16 @@ class QuotaService:
self._user_service.increment_service_use(
self._user_geocoder_config.service_type, "success_responses",
amount=amount)
self.increment_total_geocoder_use(amount)
def increment_empty_geocoder_use(self, amount=1):
self._user_service.increment_service_use(
self._user_geocoder_config.service_type, "empty_responses",
amount=amount)
self.increment_total_geocoder_use(amount)
def increment_failed_geocoder_use(self, amount=1):
self._user_service.increment_service_use(
self._user_geocoder_config.service_type, "fail_responses",
amount=amount)
self.increment_total_geocoder_use(amount)
def increment_total_geocoder_use(self, amount=1):
self._user_service.increment_service_use(

View File

@@ -1,6 +1,9 @@
redis==2.10.5
# Dependency with incsv in the import
python-dateutil==2.2
heremaps==0.0.1
googlegeocoder==0.0.1
googlemaps
# Test
mock==1.3.0

View File

@@ -0,0 +1,7 @@
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
class MalformedResult(Exception):
def __str__(self):
return repr('Malformed result. The API might have changed.')

View File

@@ -0,0 +1,49 @@
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
import googlemaps
from exceptions import MalformedResult
class Geocoder:
"""A Google Maps Geocoder wrapper for python"""
def __init__(self, client_id, client_secret):
self.client_id = self._clean_client_id(client_id)
self.client_secret = client_secret
self.geocoder = googlemaps.Client(
client_id=self.client_id, client_secret=self.client_secret)
def geocode_address(self, searchtext, city=None, state=None,
country=None):
opt_params = self._build_optional_parameters(city, state, country)
results = self.geocoder.geocode(address=searchtext, components=opt_params)
if results:
return self._extract_lng_lat_from_result(results[0])
else:
return []
def _extract_lng_lat_from_result(self, result):
try:
location = result['geometry']['location']
longitude = location['lng']
latitude = location['lat']
return [longitude, latitude]
except KeyError:
raise MalformedResult()
def _build_optional_parameters(self, city=None, state=None,
country=None):
optional_params = {}
if city:
optional_params['locality'] = city
if state:
optional_params['administrative_area'] = state
if country:
optional_params['country'] = country
return optional_params
def _clean_client_id(self, client_id):
# Consistency with how the client_id is saved in metadata
return client_id.replace('client=', '')

View File

@@ -0,0 +1,41 @@
"""
A Google Maps wrapper for the CartoDB geocoder server PostgreSQL extension
See:
https://github.com/CartoDB/geocoder-api
"""
from setuptools import setup, find_packages
setup(
name='google-geocoder',
version='0.0.1',
description='A Google Maps wrapper for the CartoDB geocoder server PostgreSQL extension',
url='https://github.com/CartoDB/geocoder-api',
author='Data Services Team - CartoDB',
author_email='dataservices@cartodb.com',
license='MIT',
classifiers=[
'Development Status :: 2 - Beta',
'Intended Audience :: Mapping comunity',
'Topic :: Maps :: Mapping Tools',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2.7',
],
keywords='maps api mapping tools',
packages=find_packages(exclude=['contrib', 'docs', 'tests']),
extras_require={
'dev': ['unittest'],
'test': ['unittest'],
}
)

View File

@@ -16,11 +16,6 @@ class NoGeocodingParams(Exception):
return repr('No params for geocoding specified')
class EmptyGeocoderResponse(Exception):
def __str__(self):
return repr('The request could not be geocoded')
class MalformedResult(Exception):
def __str__(self):
return repr('Result structure is malformed')

View File

@@ -4,10 +4,10 @@
import json
import requests
from heremaps.heremapsexceptions import BadGeocodingParams
from heremaps.heremapsexceptions import EmptyGeocoderResponse
from heremaps.heremapsexceptions import NoGeocodingParams
from heremaps.heremapsexceptions import MalformedResult
from heremaps.exception import BadGeocodingParams
from heremaps.exception import EmptyGeocoderResponse
from heremaps.exception import NoGeocodingParams
from heremaps.exception import MalformedResult
class Geocoder:
@@ -50,10 +50,6 @@ class Geocoder:
'strictlanguagemode'
] + ADDRESS_PARAMS
app_id = ''
app_code = ''
maxresults = ''
def __init__(self, app_id, app_code, maxresults=DEFAULT_MAXRESULTS,
gen=DEFAULT_GEN, host=PRODUCTION_GEOCODE_JSON_URL):
self.app_id = app_id
@@ -62,18 +58,26 @@ class Geocoder:
self.gen = gen
self.host = host
def geocode(self, params):
def geocode(self, **kwargs):
params = {}
for key, value in kwargs.iteritems():
if value:
params[key] = value
if not params:
raise NoGeocodingParams()
return self.geocode(params)
def _execute_geocode(self, params):
if not set(params.keys()).issubset(set(self.ADDRESS_PARAMS)):
raise BadGeocodingParams(params)
response = self.perform_request(params)
try:
response = self._perform_request(params)
results = response['Response']['View'][0]['Result']
return self._extract_lng_lat_from_result(results)
except IndexError:
raise EmptyGeocoderResponse()
return []
return results
def perform_request(self, params):
def _perform_request(self, params):
request_params = {
'app_id': self.app_id,
'app_code': self.app_code,
@@ -87,16 +91,7 @@ class Geocoder:
else:
response.raise_for_status()
def geocode_address(self, **kwargs):
params = {}
for key, value in kwargs.iteritems():
if value:
params[key] = value
if not params:
raise NoGeocodingParams()
return self.geocode(params)
def extract_lng_lat_from_result(self, result):
def _extract_lng_lat_from_result(self, result):
try:
location = result['Location']
except KeyError: