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:
R. Tyler Ballance 2009-04-07 18:57:31 -07:00
parent 8cf41708fc
commit d0b25719c2
2 changed files with 82 additions and 2 deletions

View File

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

23
tests/Geocode.py Normal file
View File

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