|
@@ -1,5 +1,6 @@
|
|
|
import json
|
|
|
import math
|
|
|
+import random
|
|
|
|
|
|
import requests
|
|
|
import haversine
|
|
@@ -9,6 +10,11 @@ google_api_key = "AIzaSyAqjCYR6Szph0X0H_iD6O1HenFhL9jySOo"
|
|
|
metadata_url = "https://maps.googleapis.com/maps/api/streetview/metadata"
|
|
|
mapcrunch_url = "http://www.mapcrunch.com/_r/"
|
|
|
rsv_url = "https://randomstreetview.com/data"
|
|
|
+urban_centers = []
|
|
|
+with open("./urban-centers.csv") as infile:
|
|
|
+ for line in infile:
|
|
|
+ lat, lng = line.split(",")
|
|
|
+ urban_centers.append((float(lat.strip()), float(lng.strip())))
|
|
|
|
|
|
|
|
|
def point_has_streetview(lat, lng):
|
|
@@ -31,6 +37,8 @@ def generate_coord(max_retries=100, only_america=False):
|
|
|
Returns (latitude, longitude) of usable coord (where google has data).
|
|
|
This function will attempt at most max_retries calls to map crunch to fetch
|
|
|
candidate points, and will exit as soon as a suitable candidate is found.
|
|
|
+ If no suitable candidate is found in this allotted number of retries, None is
|
|
|
+ returned.
|
|
|
|
|
|
This function calls the streetview metadata endpoint - there is no quota consumed.
|
|
|
"""
|
|
@@ -68,6 +76,8 @@ def random_street_view_generator(only_america=False):
|
|
|
"""
|
|
|
Returns a generator which will lazily use call_random_street_view to generate new
|
|
|
street view points.
|
|
|
+
|
|
|
+ The returned generator calls the streetview metadata endpoint - there is no quota consumed.
|
|
|
"""
|
|
|
points = []
|
|
|
while True:
|
|
@@ -77,6 +87,31 @@ def random_street_view_generator(only_america=False):
|
|
|
yield points.pop()
|
|
|
|
|
|
|
|
|
+def urban_coord(max_retries=100, max_dist_km=25):
|
|
|
+ """
|
|
|
+ Returns (latitude, longitude) of usable coord (where google has data) that is near
|
|
|
+ a known urban center. Points will be at most max_dist_km kilometers away. This function will
|
|
|
+ check at most max_retries points, and if none have street view data, will return None.
|
|
|
+ Otherwise, it will exit as soon as suitable point is found.
|
|
|
+
|
|
|
+ This function calls the streetview metadata endpoint - there is no quota consumed.
|
|
|
+ """
|
|
|
+
|
|
|
+ for _ in range(max_retries):
|
|
|
+ (city_lat, city_lng) = random.choice(urban_centers)
|
|
|
+ dist_km = random.random() * max_dist_km
|
|
|
+ angle_rad = random.random() * 2 * math.pi
|
|
|
+ # logic adapted from https://stackoverflow.com/a/7835325
|
|
|
+ city_lat_rad = math.radians(city_lat)
|
|
|
+ city_lng_rad = math.radians(city_lng)
|
|
|
+ pt_lat_rad = math.asin(math.sin(city_lat_rad) * math.cos(dist_km / mean_earth_radius_km) + math.cos(city_lat_rad) * math.sin(dist_km / mean_earth_radius_km) * math.cos(angle_rad))
|
|
|
+ pt_lng_rad = city_lng_rad + math.atan2(math.sin(angle_rad) * math.sin(dist_km / mean_earth_radius_km) * math.cos(city_lat_rad), math.cos(dist_km / mean_earth_radius_km) - math.sin(city_lat_rad) * math.sin(pt_lat_rad))
|
|
|
+ pt_lat = math.degrees(pt_lat_rad)
|
|
|
+ pt_lng = math.degrees(pt_lng_rad)
|
|
|
+ if point_has_streetview(pt_lat, pt_lng):
|
|
|
+ return (pt_lat, pt_lng)
|
|
|
+
|
|
|
+
|
|
|
mean_earth_radius_km = (6378 + 6357) / 2
|
|
|
|
|
|
# if you're more than 1/4 of the Earth's circumfrence away, you get 0
|