Exemplo n.º 1
0
    def setUp(self):
        # places
        self.pq_us = PlaceQuery('1200 Callowhill St, Philadelphia, PA 19107')
        self.pq_uk = PlaceQuery('32 Bond Road, Ste A, Surbiton, Surrey KT6')
        self.pq_uk_with_country_UK = PlaceQuery('32 Bond Road, Ste A, Surbiton, Surrey KT6', country='UK')
        self.pq_uk_with_country_GB = PlaceQuery('32 Bond Road, Ste A, Surbiton, Surrey KT6', country='GB')

        # candidates
        self.good = Candidate(match_addr='123 Any St', locator='address', score=85.3)
        self.better = Candidate(match_addr='123 Any St', locator='parcel', score=92)
        self.best = Candidate(match_addr='123 Any St', locator='rooftop', score=100)
        self.wolf_good = Candidate(match_addr='1200 Callowhill St', locator='address', score=76)
        self.wolf_better = Candidate(match_addr='1200 Callowhill St', locator='parcel', score=90)
        self.wolf_best = Candidate(match_addr='1200 Callowhill St', locator='rooftop',
                                   score=99.9, x=-75.158, y=39.959)
        self.wolf_340 = Candidate(match_addr='340 N 12th St', locator='rooftop',
                                  score=99.5, x=-75.158, y=39.959) # same coords
        self.inky = Candidate(match_addr='324 N Broad St', locator='rooftop',
                              score=99.9, x=-75.163, y=39.959) # same y
        self.capt_thomas = Candidate(match_addr='843 Callowhill St', locator='rooftop',
                                     score=99.9, x=-75.163, y=39.959) # same y
        self.reading_term = Candidate(match_addr='1200 Arch St', locator='rooftop',
                                      score=99.9, x=-75.163, y=39.953) # same x

        self.locators_worse_to_better = ['address', 'parcel', 'rooftop']
Exemplo n.º 2
0
 def test_pro_SnapPoints(self):
     """Take two candidates within 50 metres and eliminate one."""
     candidates_in = [Candidate(match_addr='340 N 12th St, Philadelphia, PA, 19107',
                                x=-75.158433167, y=39.958727992),
                      Candidate(match_addr='1200 Callowhill St, Philadelphia, PA, 19123',
                                x=-75.158303781, y=39.959040684)]  # about 40m away
     candidates_exp = [candidates_in[0]]  # should just keep the first one.
     candidates_out = SnapPoints(distance=50).process(candidates_in)
     self.assertEqual_(candidates_out, candidates_exp)
Exemplo n.º 3
0
    def _geocode(self, pq):
        query = {
            'q': pq.query,
            'countrycodes': pq.country,  # only takes ISO-2
            'format': 'json'
        }

        if pq.viewbox is not None:
            query = dict(
                query, **{
                    'viewbox': pq.viewbox.to_mapquest_str(),
                    'bounded': pq.bounded
                })

        response_obj = self._get_json_obj(self._endpoint, query)

        returned_candidates = []  # this will be the list returned
        for r in response_obj:
            c = Candidate()
            c.locator = 'parcel'  # we don't have one but this is the closest match
            c.entity = '%s.%s' % (r['class'], r['type'])  # ex.: "place.house"
            c.match_addr = r[
                'display_name']  # ex. "Wolf Building, 340, N 12th St, Philadelphia, Philadelphia County, Pennsylvania, 19107, United States of America" #TODO: shorten w/ pieces
            c.x = float(r['lon'])  # long, ex. -122.13 # cast to float in 1.3.4
            c.y = float(r['lat'])  # lat, ex. 47.64 # cast to float in 1.3.4
            c.wkid = self._wkid
            c.geoservice = self.__class__.__name__
            returned_candidates.append(c)
        return returned_candidates
Exemplo n.º 4
0
    def _geocode(self, location):
        query = {
            'SingleLine': location.query,
            'Address': location.address,
            'City': location.city,
            'State': location.state,
            'Zip': location.postal,
            'Country': location.country,
            'outfields': 'Loc_name,Addr_Type,Zip4_Type',
            'f': 'json'
        }

        query = self.append_token_if_needed(query)
        response_obj = self._get_json_obj(self._endpoint, query)

        try:
            wkid = response_obj['spatialReference']['wkid']
        except KeyError:
            pass

        returned_candidates = []  # this will be the list returned
        try:
            for rc in response_obj['candidates']:
                c = Candidate()
                c.locator = rc['attributes']['Loc_name']
                c.score = rc['score']
                c.match_addr = rc['address']
                c.x = rc['location']['x']
                c.y = rc['location']['y']
                c.wkid = wkid
                c.geoservice = self.__class__.__name__
                returned_candidates.append(c)
        except KeyError:
            pass
        return returned_candidates
Exemplo n.º 5
0
    def _geocode(self, location):
        query = {
            'Address': location.address,
            'City': location.city,
            'Postcode': location.postal,
            'Country': location.country,
            'outfields': 'Loc_name',
            'f': 'json'
        }

        query = self.append_token_if_needed(query)

        response_obj = self._get_json_obj(self._endpoint, query)
        returned_candidates = []  # this will be the list returned
        try:
            for rc in response_obj['candidates']:
                c = Candidate()
                c.locator = rc['attributes']['Loc_name']
                c.score = rc['score']
                c.match_addr = rc['address']
                c.x = rc['location']['x']
                c.y = rc['location']['y']
                c.wkid = self._wkid
                c.geoservice = self.__class__.__name__
                returned_candidates.append(c)
        except KeyError as ex:
            logger.warning('Received unusual JSON result from geocode: %s, %s',
                           response_obj, ex)
            return []
        return returned_candidates
Exemplo n.º 6
0
    def _geocode(self, pq):
        query = {'text': pq.query}

        if pq.country:
            query = dict(query, **{'boundary.country': pq.country})

        if pq.viewbox is not None:
            box = pq.viewbox.to_mapzen_dict()
            query = dict(query, **box)

        if hasattr(pq, 'key'):
            # Swap to the place endpoint and return a single result.
            self._endpoint = self._key_endpoint
            query = {'ids': pq.key}

        if self._settings.has_key('api_key'):
            query['api_key'] = self._settings['api_key']

        response_obj = self._get_json_obj(self._endpoint, query)
        returned_candidates = []  # this will be the list returned
        features_in_response = response_obj['features']
        for r in features_in_response:
            properties = r['properties']
            geometry = r['geometry']

            score = 100 * float(properties['confidence']) \
                    if properties.has_key('confidence') else 0
            locality = properties['locality'] \
                       if properties.has_key('locality') else ''
            region = properties['region'] \
                     if properties.has_key('region') else ''
            label = properties['label'] \
                    if properties.has_key('label') else ''
            layer = properties['layer'] \
                    if properties.has_key('layer') else ''

            c = Candidate()
            c.locator = layer
            c.match_addr = label
            c.match_region = region
            c.match_city = locality
            c.locator_type = layer
            c.x = float(geometry['coordinates'][0])
            c.y = float(geometry['coordinates'][1])
            c.score = score
            c.wkid = self._wkid
            c.geoservice = self.__class__.__name__
            returned_candidates.append(c)
        return returned_candidates
Exemplo n.º 7
0
    def _geocode(self, pq):
        def get_appended_location(location, **kwargs):
            """Add key/value pair to given dict only if value is not empty string."""
            for kw in kwargs:
                if kwargs[kw] != '':
                    location = dict(location, **{kw: kwargs[kw]})
            return location

        location = {}
        location = get_appended_location(location, street=pq.query)
        if location == {}:
            location = get_appended_location(location, street=pq.address)
        location = get_appended_location(location,
                                         city=pq.city,
                                         county=pq.subregion,
                                         state=pq.state,
                                         postalCode=pq.postal,
                                         country=pq.country)
        json_ = dict(location=location)
        json_ = json.dumps(json_)
        logger.debug('MQ json: %s', json_)
        query = dict(key=unquote(self._settings['api_key']), json=json_)
        if pq.viewbox is not None:
            query = dict(query, viewbox=pq.viewbox.to_mapquest_str())
        response_obj = self._get_json_obj(self._endpoint, query)
        logger.debug('MQ RESPONSE: %s', response_obj)
        returned_candidates = []  # this will be the list returned
        for r in response_obj['results'][0]['locations']:
            c = Candidate()
            c.locator = r['geocodeQuality']
            c.confidence = r[
                'geocodeQualityCode']  #http://www.mapquestapi.com/geocoding/geocodequality.html
            match_addr_elements = [
                'street', 'adminArea5', 'adminArea3', 'adminArea2',
                'postalCode'
            ]  # similar to ESRI
            c.match_addr = ', '.join(
                [r[k] for k in match_addr_elements if k in r])
            c.x = r['latLng']['lng']
            c.y = r['latLng']['lat']
            c.wkid = 4326
            c.geoservice = self.__class__.__name__
            returned_candidates.append(c)
        return returned_candidates
Exemplo n.º 8
0
    def _get_candidates_from_record_set(self, record_set):
        """
        Given a RecordSet, create a list of Candidate objects for processing
        """
        candidates = []
        for record in record_set.Records.Record:

            c_dict = {}

            for field, value in zip(record_set.Fields.FieldArray.Field,
                                    record.Values.Value):

                if field.Name in self._mapping:
                    c_dict[self._mapping[field.Name]] = value

            candidate = Candidate(**c_dict)
            candidate.wkid = self._wkid
            candidate.geoservice = self.__class__.__name__
            candidates.append(candidate)
        return candidates
Exemplo n.º 9
0
    def _make_candidate_from_result(self, result):
        """ Make a Candidate from a Google geocoder results dictionary. """
        candidate = Candidate()
        candidate.match_addr = result['formatted_address']
        candidate.x = result['geometry']['location']['lng']
        candidate.y = result['geometry']['location']['lat']
        candidate.locator = self.LOCATOR_MAPPING.get(result['geometry']['location_type'], '')
        candidate.entity_types = result['types']
        candidate.partial_match = result.get('partial_match', False)

        component_lookups = {
            'city': {'type': 'locality', 'key': 'long_name'},
            'subregion': {'type': 'administrative_area_level_2', 'key': 'long_name'},
            'region': {'type': 'administrative_area_level_1', 'key': 'short_name'},
            'postal': {'type': 'postal_code', 'key': 'long_name'},
            'country': {'type': 'country', 'key': 'short_name'},
        }
        for (field, lookup) in component_lookups.items():
            setattr(candidate, 'match_' + field, self._get_component_from_result(result, lookup))
        candidate.geoservice = self.__class__.__name__
        return candidate
Exemplo n.º 10
0
    def _geocode(self, pq):
        if pq.query.strip() == '':
            # No single line query string; use address elements:
            query = {
                'addressLine': pq.address,
                'locality': pq.city,
                'adminDistrict': pq.state,
                'postalCode': pq.postal,
                'countryRegion': pq.country
            }
        else:
            query = {'query': pq.query}

        if pq.viewbox is not None:
            query = dict(query, **{'umv': pq.viewbox.to_bing_str()})
        if hasattr(pq, 'culture'):
            query = dict(query, c=pq.culture)
        if hasattr(pq, 'user_ip'):
            query = dict(query, uip=pq.user_ip)
        if hasattr(pq, 'user_lat') and hasattr(pq, 'user_lon'):
            query = dict(query, **{'ul': '%f,%f' % (pq.user_lat, pq.user_lon)})

        addl_settings = {'key': self._settings['api_key']}
        query = dict(query, **addl_settings)
        response_obj = self._get_json_obj(self._endpoint, query)
        returned_candidates = []  # this will be the list returned
        for r in response_obj['resourceSets'][0]['resources']:
            c = Candidate()
            c.entity = r['entityType']
            c.locator = r['geocodePoints'][0][
                'calculationMethod']  # ex. "Parcel"
            c.confidence = r['confidence']  # High|Medium|Low
            c.match_addr = r[
                'name']  # ex. "1 Microsoft Way, Redmond, WA 98052"
            c.x = r['geocodePoints'][0]['coordinates'][1]  # long, ex. -122.13
            c.y = r['geocodePoints'][0]['coordinates'][0]  # lat, ex. 47.64
            c.wkid = 4326
            c.geoservice = self.__class__.__name__
            returned_candidates.append(c)
        return returned_candidates
Exemplo n.º 11
0
    def _geocode(self, pq):
        query = {'format': 'json', 'benchmark': 'Public_AR_Current'}

        if pq.query:
            _this_endpoint = '%s%s' % (self._endpoint_base, 'onelineaddress')
            query['address'] = pq.query
        else:
            _this_endpoint = '%s%s' % (self._endpoint_base, 'address')
            query['street'] = pq.address
            query['city'] = pq.city
            query['state'] = pq.state
            query['zip'] = pq.postal

        logger.debug('CENSUS QUERY: %s', query)
        response_obj = self._get_json_obj(_this_endpoint, query)
        logger.debug('CENSUS RESPONSE: %s', response_obj)

        returned_candidates = []  # this will be the list returned
        for r in response_obj['result']['addressMatches']:
            c = Candidate()
            c.match_addr = r['matchedAddress']
            c.x = r['coordinates']['x']
            c.y = r['coordinates']['y']
            c.geoservice = self.__class__.__name__
            # Optional address component fields.
            for in_key, out_key in [('city', 'match_city'),
                                    ('state', 'match_region'),
                                    ('zip', 'match_postal')]:
                setattr(c, out_key, r['addressComponents'].get(in_key, ''))
            setattr(c, 'match_subregion',
                    '')  # No county from Census geocoder.
            setattr(c, 'match_country',
                    'USA')  # Only US results from Census geocoder
            setattr(c, 'match_streetaddr', self._street_addr_from_response(r))
            returned_candidates.append(c)
        return returned_candidates
Exemplo n.º 12
0
    def _geocode(self, pq):
        """
        :arg PlaceQuery pq: PlaceQuery object to use for geocoding
        :returns: list of location Candidates
        """
        #: List of desired output fields
        #: See `ESRI docs <http://geocode.arcgis.com/arcgis/geocoding.html#output>_` for details
        outFields = (
            'Loc_name',
            #'Shape',
            'Score',
            'Match_Addr',  #based on address standards for the country
            #'Address', # returned by default
            #'Country' # 3-digit ISO 3166-1 code for a country. Example: Canada = "CAN"
            #'Admin',
            #'DepAdmin',
            #'SubAdmin',
            #'Locality',
            #'Postal',
            #'PostalExt',
            'Addr_Type',
            #'Type',
            #'Rank',
            'AddNum',
            'StPreDir',
            'StPreType',
            'StName',
            'StType',
            'StDir',
            #'Side',
            #'AddNumFrom',
            #'AddNumTo',
            #'AddBldg',
            'City',
            'Subregion',
            'Region',
            'Postal',
            'Country',
            #'Ymax',
            #'Ymin',
            #'Xmin',
            #'Xmax',
            #'X',
            #'Y',
            'DisplayX',
            'DisplayY',
            #'LangCode',
            #'Status',
        )
        outFields = ','.join(outFields)
        query = dict(
            f='json',  # default HTML. Other options are JSON and KMZ.
            outFields=outFields,
            #outSR=WKID, defaults to 4326
            maxLocations=20,  # default 1; max is 20
        )

        # Postal-code only searches work in the single-line but not multipart geocoder
        # Remember that with the default postprocessors, postcode-level results will be eliminated
        if pq.query == pq.address == '' and pq.postal != '':
            pq.query = pq.postal

        if pq.query == '':  # multipart
            method = 'findAddressCandidates'
            query = dict(
                query,
                Address=pq.
                address,  # commonly represents the house number and street name of a complete address
                Neighborhood=pq.neighborhood,
                City=pq.city,
                Subregion=pq.subregion,
                Region=pq.state,
                Postal=pq.postal,
                #PostalExt=
                CountryCode=pq.
                country,  # full country name or ISO 3166-1 2- or 3-digit country code
            )
            if pq.bounded and pq.viewbox is not None:
                query = dict(query, searchExtent=pq.viewbox.to_esri_wgs_json())
        else:  # single-line
            method = 'find'
            magic_key = pq.key if hasattr(pq, 'key') else ''
            query = dict(
                query,
                text=pq.
                query,  # This can be a street address, place name, postal code, or POI.
                sourceCountry=pq.
                country,  # full country name or ISO 3166-1 2- or 3-digit country code
            )
            if magic_key:
                query[
                    'magicKey'] = magic_key  # This is a lookup key returned from the suggest endpoint.
            if pq.bounded and pq.viewbox is not None:
                query = dict(query, bbox=pq.viewbox.to_esri_wgs_json())

        endpoint = self._endpoint + '/' + method
        response_obj = self._get_json_obj(endpoint, query)
        returned_candidates = []  # this will be the list returned
        try:
            if method == 'find':
                locations = response_obj['locations']
            else:
                locations = response_obj['candidates']

            for location in locations:
                c = Candidate()
                if method == 'find':  # singlepart
                    attributes = location['feature']['attributes']
                else:  # findAddressCandidates / multipart
                    attributes = location['attributes']
                c.match_addr = attributes['Match_Addr']
                c.locator = attributes['Loc_name']
                c.locator_type = attributes['Addr_Type']
                c.score = attributes['Score']
                c.x = attributes[
                    'DisplayX']  # represents the actual location of the address.
                c.y = attributes['DisplayY']
                c.wkid = response_obj['spatialReference']['wkid']
                c.geoservice = self.__class__.__name__

                # Optional address component fields.
                for in_key, out_key in [('City', 'match_city'),
                                        ('Subregion', 'match_subregion'),
                                        ('Region', 'match_region'),
                                        ('Postal', 'match_postal'),
                                        ('Country', 'match_country')]:
                    setattr(c, out_key, attributes.get(in_key, ''))
                setattr(c, 'match_streetaddr',
                        self._street_addr_from_response(attributes))
                returned_candidates.append(c)
        except KeyError:
            pass
        return returned_candidates