lib.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import json
  2. import math
  3. import requests
  4. import haversine
  5. # Google API key, with access to Street View Static API
  6. google_api_key = "AIzaSyAqjCYR6Szph0X0H_iD6O1HenFhL9jySOo"
  7. metadata_url = "https://maps.googleapis.com/maps/api/streetview/metadata"
  8. mapcrunch_url = "http://www.mapcrunch.com/_r/"
  9. def generate_coord():
  10. """
  11. Returns (latitude, longitude) of usable coord (where google has data).
  12. This function will run until a suitable coordinate is found.
  13. This function calls the streetview metadata endpoint - there is no quota consumed
  14. """
  15. points_res = requests.get(mapcrunch_url).text
  16. points_js = json.loads(points_res.strip("while(1); "))
  17. while True:
  18. for lat, lng in points_js["points"]:
  19. params = {
  20. "key": google_api_key,
  21. "location": f"{lat},{lng}",
  22. }
  23. js = requests.get(metadata_url, params=params).json()
  24. if js["status"] != "ZERO_RESULTS":
  25. return (lat, lng)
  26. mean_earth_radius_km = (6378 + 6357) / 2
  27. # the farthest you can be from another point on Earth
  28. antipode_dist_km = math.pi * mean_earth_radius_km
  29. min_dist_km = 0.15 # if you're within 150m, you get a perfect score
  30. # if you're more than 1/4 of the Earth away, you get 0
  31. max_dist_km = antipode_dist_km / 2
  32. # this has been tuned by hand based on the max dist to get a nice Gaussian
  33. exp_denom = max_dist_km * max_dist_km / 4
  34. perfect_score = 5000
  35. def score(target, guess):
  36. """
  37. Takes in two (latitude, longitude) pairs and produces an int score.
  38. Score is in the (inclusive) range [0, 5000]
  39. Higher scores are closer.
  40. Returns (score, distance in km)
  41. """
  42. dist_km = haversine.haversine(target, guess)
  43. if dist_km <= min_dist_km:
  44. return perfect_score, dist_km
  45. if dist_km >= max_dist_km:
  46. return 0, dist_km
  47. # Gaussian, with some manual tuning to get good fall off
  48. exponent = -((dist_km - min_dist_km) ^ 2) / exp_denom
  49. return int(perfect_score * math.exp(exponent)), dist_km