示例#1
0
    def test_pro_streetnumber_ReplaceRangeWithNumber(self):
        """Test ReplaceRangeWithNumber preprocessor."""
        place_in = PlaceQuery('4452-54 Main Street, Philadelphia')  # Mom's Pizza in Manayunk
        place_out = ReplaceRangeWithNumber().process(place_in)
        query_exp = '4452 Main Street, Philadelphia'
        self.assertEqual_(place_out.query, query_exp)

        zip_plus_4 = '19127-1112'
        place_in = PlaceQuery(zip_plus_4)  # sets PlaceQuery.query to zip_plus_4 on init
        place_out = ReplaceRangeWithNumber().process(place_in)
        self.assertEqual_(place_out.query, zip_plus_4)
示例#2
0
class Nominatim(GeocodeService):
    """
    Class to geocode using `Nominatim services hosted
    by MapQuest <http://open.mapquestapi.com/nominatim/>`_.
    """
    _wkid = 4326
    _endpoint = 'http://open.mapquestapi.com/nominatim/v1/search'

    DEFAULT_ACCEPTED_ENTITIES = [
        'building.', 'historic.castle', 'leisure.ice_rink',
        'leisure.miniature_golf', 'leisure.sports_centre', 'lesiure.stadium',
        'leisure.track', 'lesiure.water_park', 'man_made.lighthouse',
        'man_made.works', 'military.barracks', 'military.bunker', 'office.',
        'place.house', 'amenity.', 'power.generator', 'railway.station',
        'shop.', 'tourism.'
    ]

    DEFAULT_REJECTED_ENTITIES = [
        'amenity.drinking_water', 'amentity.bicycle_parking',
        'amentity.ev_charging', 'amentity.grit_bin', 'amentity.atm',
        'amentity.hunting_stand', 'amentity.post_box'
    ]

    DEFAULT_PREPROCESSORS = [ReplaceRangeWithNumber()
                             ]  # 766-68 Any St. -> 766 Any St.
    """Preprocessors to use with this geocoder service, in order of desired execution."""

    DEFAULT_POSTPROCESSORS = [
        AttrFilter(DEFAULT_ACCEPTED_ENTITIES, 'entity', exact_match=False),
        AttrExclude(DEFAULT_REJECTED_ENTITIES, 'entity')
    ]
    """Postprocessors to use with this geocoder service, in order of desired execution."""
    def __init__(self, preprocessors=None, postprocessors=None, settings=None):
        preprocessors = Nominatim.DEFAULT_PREPROCESSORS if preprocessors is None else preprocessors
        postprocessors = Nominatim.DEFAULT_POSTPROCESSORS if postprocessors is None else postprocessors
        GeocodeService.__init__(self, preprocessors, postprocessors, settings)

    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
示例#3
0
class Mapzen(GeocodeService):
    """
    Class to geocode using `Mapzen search service
    <https://mapzen.com/projects/search>`_.

    Settings used by the Mapzen GeocodeService object include:
     * api_key --  The API key used to access search service.

    """
    _wkid = 4326

    # 766-68 Any St. -> 766 Any St.
    DEFAULT_PREPROCESSORS = [ReplaceRangeWithNumber()]
    DEFAULT_POSTPROCESSORS = []

    def __init__(self, preprocessors=None, postprocessors=None, settings=None):
        if settings.has_key('api_version'):
            self._api_version = 'v' + str(settings['api_version'])
        else:
            self._api_version = 'v1'

        if settings.has_key('instance_url'):
            self._base_url = settings['instance_url']
        else:
            self._base_url = 'https://search.mapzen.com'

        self._default_endpoint = urljoin(
            self._base_url, posixjoin(self._api_version, 'search'))
        self._key_endpoint = urljoin(self._base_url,
                                     posixjoin(self._api_version, 'place'))
        self._endpoint = self._default_endpoint

        preprocessors = Mapzen.DEFAULT_PREPROCESSORS if preprocessors is None else preprocessors
        postprocessors = Mapzen.DEFAULT_POSTPROCESSORS if postprocessors is None else postprocessors
        GeocodeService.__init__(self, preprocessors, postprocessors, settings)

    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
示例#4
0
class Bing(GeocodeService):
    """
    Class to geocode using Bing services:
     * `Find a Location by Query <http://msdn.microsoft.com/en-us/library/ff701711.aspx>`_
     * `Find a Location by Address <http://msdn.microsoft.com/en-us/library/ff701714.aspx>`_

    Settings used by the Bing GeocodeService object may include:
     * api_key --  The API key used to access Bing services.

    """
    _endpoint = 'http://dev.virtualearth.net/REST/v1/Locations'

    DEFAULT_PREPROCESSORS = [ReplaceRangeWithNumber()]

    DEFAULT_POSTPROCESSORS = [
        AttrMigrator('confidence', 'score', {
            'High': 100,
            'Medium': 85,
            'Low': 50
        }),
        UseHighScoreIfAtLeast(100),
        AttrFilter([
            'Address', 'AdministrativeBuilding', 'AgriculturalStructure',
            'BusinessName', 'BusinessStructure', 'BusStation', 'Camp',
            'Church', 'CityHall', 'CommunityCenter', 'ConventionCenter',
            'Courthouse', 'Factory', 'FerryTerminal', 'FishHatchery', 'Fort',
            'Garden', 'Geyser', 'Heliport', 'IndustrialStructure',
            'InformationCenter', 'Junction', 'LandmarkBuilding', 'Library',
            'Lighthouse', 'Marina', 'MedicalStructure', 'MetroStation', 'Mine',
            'Mission', 'Monument', 'Mosque', 'Museum', 'NauticalStructure',
            'NavigationalStructure', 'OfficeBuilding', 'ParkAndRide',
            'PlayingField', 'PoliceStation', 'PostOffice', 'PowerStation',
            'Prison', 'RaceTrack', 'ReligiousStructure', 'RestArea', 'Ruin',
            'ShoppingCenter', 'Site', 'SkiArea', 'Spring', 'Stadium', 'Temple',
            'TouristStructure'
        ], 'entity'),
        AttrRename(
            'locator',
            dict(Rooftop='rooftop',
                 Parcel='parcel',
                 ParcelCentroid='parcel',
                 Interpolation='interpolation',
                 InterpolationOffset='interpolation_offset')),
        AttrSorter(
            ['rooftop', 'parcel', 'interpolation_offset', 'interpolation'],
            'locator'),
        AttrSorter(['Address'], 'entity'),
        ScoreSorter(),
        GroupBy(('x', 'y')),
        GroupBy('match_addr')
    ]
    DEFAULT_POSTPROCESSORS = []

    def __init__(self, preprocessors=None, postprocessors=None, settings=None):
        preprocessors = Bing.DEFAULT_PREPROCESSORS if preprocessors is None else preprocessors
        postprocessors = Bing.DEFAULT_POSTPROCESSORS if postprocessors is None else postprocessors
        GeocodeService.__init__(self, preprocessors, postprocessors, settings)

    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