random_street_view.py 2.4 KB

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