providers.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. from __future__ import unicode_literals, division, print_function
  2. import requests
  3. import logging
  4. import re
  5. logger = logging.getLogger(__name__)
  6. class AltitudeProvider(object):
  7. url_template = "http://example.com/{lon}/{lat}"
  8. def parse_answer(self, req):
  9. """[req] is a Request instances from requests. Should return a float."""
  10. try:
  11. return float(req.text)
  12. except ValueError:
  13. raise
  14. class GeonamesProvider(AltitudeProvider):
  15. url_template = "http://api.geonames.org/astergdem?lat={lat}&lng={lon}&username=celutz&style=full"
  16. class GeoportailProvider(AltitudeProvider):
  17. url_template = "https://wxs.ign.fr/an7nvfzojv5wa96dsga5nk8w/alti/rest/elevation.xml?lon={lon}&lat={lat}&indent=false&crs=%27CRS:84%27&zonly=true"
  18. def parse_answer(self, req):
  19. m = re.search(r'<z>(.*)</z>', req.text)
  20. if m == None:
  21. raise ValueError
  22. return float(m.group(1))
  23. # Main function
  24. def get_altitude(providers, timeout, latitude, longitude):
  25. """Given a list of altitude provider classes, and a timeout for each
  26. provider, try them all in order until we obtain a reasonable altitude
  27. for the given coordinates.
  28. If all providers fail, returns None.
  29. """
  30. # Try all providers in order
  31. for Provider in providers:
  32. name = Provider.__name__
  33. logger.info("Trying {}…".format(name))
  34. provider = Provider()
  35. url = provider.url_template.format(lat=latitude, lon=longitude)
  36. try:
  37. r = requests.get(url, timeout=timeout)
  38. except requests.exceptions.ReadTimeout:
  39. logger.warning("{} timeout out after {} seconds".format(name, timeout))
  40. continue
  41. if r.status_code != 200:
  42. continue
  43. try:
  44. alt = provider.parse_answer(r)
  45. logger.info("Got {}m".format(alt))
  46. if alt < 0:
  47. continue
  48. return alt
  49. except ValueError:
  50. continue
  51. # If all providers failed, return nothing