providers.py 2.0 KB

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