1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- import json
- import math
- import requests
- import haversine
- # Google API key, with access to Street View Static API
- google_api_key = "AIzaSyAqjCYR6Szph0X0H_iD6O1HenFhL9jySOo"
- metadata_url = "https://maps.googleapis.com/maps/api/streetview/metadata"
- mapcrunch_url = "http://www.mapcrunch.com/_r/"
- def generate_coord():
- """
- Returns (latitude, longitude) of usable coord (where google has data).
- This function will run until a suitable coordinate is found.
- This function calls the streetview metadata endpoint - there is no quota consumed
- """
- points_res = requests.get(mapcrunch_url).text
- points_js = json.loads(points_res.strip("while(1); "))
- while True:
- for lat, lng in points_js["points"]:
- params = {
- "key": google_api_key,
- "location": f"{lat},{lng}",
- }
- js = requests.get(metadata_url, params=params).json()
- if js["status"] != "ZERO_RESULTS":
- return (lat, lng)
- mean_earth_radius_km = (6378 + 6357) / 2
- # the farthest you can be from another point on Earth
- antipode_dist_km = math.pi * mean_earth_radius_km
- min_dist_km = 0.15 # if you're within 150m, you get a perfect score
- # if you're more than 1/4 of the Earth away, you get 0
- max_dist_km = antipode_dist_km / 2
- # this has been tuned by hand based on the max dist to get a nice Gaussian
- exp_denom = max_dist_km * max_dist_km / 4
- perfect_score = 5000
- def score(target, guess):
- """
- Takes in two (latitude, longitude) pairs and produces an int score.
- Score is in the (inclusive) range [0, 5000]
- Higher scores are closer.
- Returns (score, distance in km)
- """
- dist_km = haversine.haversine(target, guess)
- if dist_km <= min_dist_km:
- return perfect_score, dist_km
- if dist_km >= max_dist_km:
- return 0, dist_km
- # Gaussian, with some manual tuning to get good fall off
- exponent = -((dist_km - min_dist_km) ^ 2) / exp_denom
- return int(perfect_score * math.exp(exponent)), dist_km
|