Add support for "forward" geocoding, i.e. finding the lat/long and other details via the Virtual Earth API
Not sure how useful this is to anybody, but I suppose having lat/long is nice. Signed-off-by: R. Tyler Ballance <tyler@slide.com>
This commit is contained in:
parent
8cf41708fc
commit
d0b25719c2
61
Geocoder.py
61
Geocoder.py
|
@ -1,10 +1,32 @@
|
|||
|
||||
class Location(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s at %s> %s\n' % (self.__class__.__name__, hex(id(self)), ', '.join(['%s=%s' % (k, v) for k, v in self.__dict__.iteritems() if type(self.__dict__[k]) in [basestring, int, float]]))
|
||||
|
||||
@classmethod
|
||||
def locationFromGeocodeLocation(cls, holder):
|
||||
'''
|
||||
Return an instantiated Location object based on the data sitting in:
|
||||
_GeocodeResult._Results._GeocodeResult[0]._Locations._GeocodeLocation
|
||||
|
||||
Expected attributes:
|
||||
.latitude
|
||||
.longitude
|
||||
.altitude
|
||||
.calculationMethod
|
||||
'''
|
||||
return cls(**holder.__dict__)
|
||||
|
||||
|
||||
class Address(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s at %s> %s\n' % (self.__class__.__name__, hex(id(self)), ', '.join(['%s=%s' % (k, v) for k, v in self.__dict__.iteritems() if isinstance(self.__dict__[k], basestring) or k == 'address']))
|
||||
return '<%s at %s> %s\n' % (self.__class__.__name__, hex(id(self)), ', '.join(['%s=%s' % (k, v) for k, v in self.__dict__.iteritems() if type(self.__dict__[k]) in [basestring, list] or k == 'address']))
|
||||
|
||||
@classmethod
|
||||
def addressFromSoapResponse(cls, holder):
|
||||
|
@ -20,7 +42,15 @@ class Address(object):
|
|||
# The _Address.__dict__ dictionary looks something like this:
|
||||
# {'_District': '', '_PostalCode': '95014-2084', '_FormattedAddress': '1 Infinite Loop, Cupertino, CA 95014-2084', '_AdminDistrict': 'CA', '_CountryRegion': 'United States', '_AddressLine': '1 Infinite Loop', '_Locality': 'Cupertino', '_PostalTown': ''}
|
||||
address = dict(((k[1:], v) for k, v in holder._Address.__dict__.iteritems()))
|
||||
return cls(displayName=holder._DisplayName, confidence=holder._Confidence, entityType=holder._EntityType, address=address)
|
||||
attributes = {'address' : address, 'confidence' : holder._Confidence, 'entityType' : holder._EntityType,
|
||||
'displayName' : holder._DisplayName, 'locations' : [],}
|
||||
|
||||
if hasattr(holder, '_Locations'):
|
||||
print holder._Locations
|
||||
for _loc in holder._Locations._GeocodeLocation:
|
||||
attributes['locations'].append(Location.locationFromGeocodeLocation(_loc))
|
||||
|
||||
return cls(**attributes)
|
||||
|
||||
|
||||
class Geocoder(object):
|
||||
|
@ -58,5 +88,32 @@ class Geocoder(object):
|
|||
|
||||
results = result._ReverseGeocodeResult._Results._GeocodeResult
|
||||
return [Address.addressFromSoapResponse(piece) for piece in results]
|
||||
|
||||
def query(self, address):
|
||||
if not self.production:
|
||||
from staging import GeocodeService_client
|
||||
from staging import GeocodeService_types
|
||||
else:
|
||||
from production import GeocodeService_client
|
||||
from production import GeocodeService_types
|
||||
locator = GeocodeService_client.GeocodeServiceLocator()
|
||||
service = locator.getBasicHttpBinding_IGeocodeService()
|
||||
request = GeocodeService_client.IGeocodeService_Geocode_InputMessage()
|
||||
request._request = GeocodeService_types.ns5.GeocodeRequest_Def(self.token)
|
||||
|
||||
credentials = GeocodeService_types.ns3.Credentials_Dec()
|
||||
credentials._ApplicationId = None
|
||||
credentials._Token = self.token
|
||||
|
||||
request._request._Culture = None
|
||||
request._request._Credentials = credentials
|
||||
request._request._ExecutionOptions = None
|
||||
|
||||
request._request._Query = address
|
||||
|
||||
result = service.Geocode(request)
|
||||
results = result._GeocodeResult._Results._GeocodeResult
|
||||
return [Address.addressFromSoapResponse(piece) for piece in results]
|
||||
|
||||
|
||||
# vim: set expandtab:
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import os
|
||||
import unittest
|
||||
|
||||
USER = os.getenv('VE_USER')
|
||||
PASSWORD = os.getenv('VE_PASSWORD')
|
||||
|
||||
import GetToken
|
||||
import Geocoder
|
||||
|
||||
class GeocodeAppleInc(unittest.TestCase):
|
||||
def setUp(self):
|
||||
opts = GetToken.OptionsProxy(user=USER, clientip='0.0.0.0', tokenvalidity=15, production=False)
|
||||
self.token = GetToken.getToken(opts, PASSWORD)
|
||||
|
||||
def runTest(self):
|
||||
geo = Geocoder.Geocoder(token=self.token)
|
||||
results = geo.query('The Metreon, San Francisco')
|
||||
assert len(results) == 1, (results, 'We expected one result for the Metreon')
|
||||
print results
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in New Issue