random_street_view.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import requests
  2. from .shared import point_has_streetview, GeoPointSource, CachedGeoPointSource, ExhaustedSourceError, GeoPointSourceGroup
  3. RSV_URL = "https://randomstreetview.com/data"
  4. def call_random_street_view(country_lock=None):
  5. """
  6. Returns an array of (some number of) tuples, each being (latitude, longitude).
  7. All points will be valid streetview coordinates. There is no guarantee as to the
  8. length of this array (it may be empty), but it will never be None.
  9. This function calls the streetview metadata endpoint - there is no quota consumed.
  10. """
  11. try:
  12. rsv_js = requests.post(RSV_URL, data={"country": country_lock.lower() if country_lock is not None else "all"}).json()
  13. except:
  14. return []
  15. if not rsv_js["success"]:
  16. return []
  17. return [
  18. (point["lat"], point["lng"])
  19. for point in rsv_js["locations"]
  20. if point_has_streetview(point["lat"], point["lng"])
  21. ]
  22. class RSVPointSource(GeoPointSource):
  23. def __init__(self, country_lock=None, max_attempts=100):
  24. self.country_lock = country_lock
  25. self.max_attempts = max_attempts
  26. def get_name(self):
  27. return f"RSV-{self.country_lock or 'all'}"
  28. def get_points(self, n):
  29. attempts = 0
  30. points = []
  31. while len(points) < n:
  32. if attempts > self.max_attempts:
  33. raise ExhaustedSourceError()
  34. points.extend(call_random_street_view(country_lock=self.country_lock))
  35. attempts += 1
  36. return points
  37. WORLD_SOURCE = CachedGeoPointSource(RSVPointSource(), 10)
  38. VALID_COUNTRIES = ("ad", "au", "ar", "bd", "be", "bt", "bw",
  39. "br", "bg", "kh", "ca", "cl", "hr", "co",
  40. "cz", "dk", "ae", "ee", "fi", "fr", "de",
  41. "gr", "hu", "hk", "is", "id", "ie", "it",
  42. "il", "jp", "lv", "lt", "my", "mx", "nl",
  43. "nz", "no", "pe", "pl", "pt", "ro", "ru",
  44. "sg", "sk", "si", "za", "kr", "es", "sz",
  45. "se", "ch", "tw", "th", "ua", "gb", "us")
  46. COUNTRY_SOURCES = {
  47. "us": CachedGeoPointSource(RSVPointSource("us"), 10), # cache US specifically since it is commonly used
  48. **{ k: RSVPointSource(k) for k in VALID_COUNTRIES if k not in ("us",) }
  49. }
  50. SOURCE_GROUP = GeoPointSourceGroup(COUNTRY_SOURCES, WORLD_SOURCE)