slideinc / pyve forked from rtyler/pyve

Python Virtual Earth client for using Microsoft Virtual Earth web services

pyve / Geocoder.py
100644 119 lines (92 sloc) 4.916 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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 type(self.__dict__[k]) in [basestring, list] or k == 'address']))
 
    @classmethod
    def addressFromSoapResponse(cls, holder):
        '''
Return an instantiated Address object based on the returned data from the SOAP ReverseGeocode API
 
Expected attributes:
.address
.displayName
.confidence
.entityType
'''
        # 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()))
        attributes = {'address' : address, 'confidence' : holder._Confidence, 'entityType' : holder._EntityType,
                'displayName' : holder._DisplayName, 'locations' : [],}
 
        if hasattr(holder, '_Locations'):
            for _loc in holder._Locations._GeocodeLocation:
                attributes['locations'].append(Location.locationFromGeocodeLocation(_loc))
 
        return cls(**attributes)
 
 
class Geocoder(object):
    def __init__(self, *args, **kwargs):
        self.token = kwargs['token']
        self.production = kwargs.get('production')
        
    def reverse(self, latitude, longitude, altitude=0):
        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_ReverseGeocode_InputMessage()
        request._request = GeocodeService_types.ns5.GeocodeRequest_Def(self.token)
 
        location = GeocodeService_types.ns3.Location_Dec()
        location._Altitude = altitude
        location._Latitude = latitude
        location._Longitude = longitude
 
        credentials = GeocodeService_types.ns3.Credentials_Dec()
        credentials._ApplicationId = None
        credentials._Token = self.token
 
        request._request._Location = location
        request._request._Culture = None
        request._request._Credentials = credentials
        request._request._ExecutionOptions = None
 
        result = service.ReverseGeocode(request)
 
        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: