lab_weather/geocoder/arcgis.py

105 lines
3.0 KiB
Python

#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import logging
import json
from geocoder.base import OneResult, MultipleResultsQuery
class ArcgisResult(OneResult):
def __init__(self, json_content):
# create safe shortcuts
self._feature = json_content.get('feature', {})
# proceed with super.__init__
super(ArcgisResult, self).__init__(json_content)
@property
def address(self):
return self.raw.get('name', '')
@property
def lat(self):
return self._feature.get('geometry', {}).get('y')
@property
def lng(self):
return self._feature.get('geometry', {}).get('x')
@property
def score(self):
return self._feature.get('attributes', {}).get('Score', '')
@property
def quality(self):
return self._feature.get('attributes', {}).get('Addr_Type', '')
@property
def bbox(self):
_extent = self.raw.get('extent')
if _extent:
south = _extent.get('ymin')
west = _extent.get('xmin')
north = _extent.get('ymax')
east = _extent.get('xmax')
return self._get_bbox(south, west, north, east)
class ArcgisQuery(MultipleResultsQuery):
"""
ArcGIS REST API
=======================
The World Geocoding Service finds addresses and places in all supported countries
from a single endpoint. The service can find point locations of addresses,
business names, and so on. The output points can be visualized on a map,
inserted as stops for a route, or loaded as input for a spatial analysis.
an address, retrieving imagery metadata, or creating a route.
API Reference
-------------
https://developers.arcgis.com/rest/geocode/api-reference/geocoding-find.htm
"""
provider = 'arcgis'
method = 'geocode'
_URL = 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find'
_RESULT_CLASS = ArcgisResult
_KEY_MANDATORY = False
def _build_params(self, location, provider_key, **kwargs):
# backward compatitibility for 'limit' (now maxRows)
if 'limit' in kwargs:
logging.warning(
"argument 'limit' in OSM is deprecated and should be replaced with maxRows")
kwargs['maxRows'] = kwargs['limit']
# build params
return {
'f': 'json',
'text': location,
'maxLocations': kwargs.get('maxRows', 1),
}
def _adapt_results(self, json_response):
return json_response['locations']
def _catch_errors(self, json_response):
status = json_response.get('error')
if status:
self.error = status.get('code')
self.message = status.get('message')
self.details = status.get('details')
return self.error
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
g = ArcgisQuery('Toronto')
g.debug()
g = ArcgisQuery('Ottawa, Ontario', maxRows=5)
print(json.dumps(g.geojson, indent=4))
print([result.address for result in g][:3])