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