This is a collection of projects that I've started, but have not made the time to finish. I'm posting them here with the hope that I, or someone else, will find them useful later
I enjoy being able to walk to the gym, coffee shop, etc.
I wanted a way to determine the best neighborhoods based on their proximity to these things.
Done:
Interface with Google Places API
Use kepler.gl to visualize preliminary data
To do:
Create function to take in any city, and create a grid of latitude and longitude
Figure out why only results on the west side of town are showing up (probably because of a dumb mistake in the for loop)
Generate heat map from data
Update June 2, 2024: I found a great tool that does this in the Recommendo newsletter.
import numpy as np
import pandas as pd
import requests
import json
from urllib.parse import urlencode
# Create a grid of (latitude, longitude) for given city
# This is hard-coded for Austin now - fix this later (maybe with https://stackoverflow.com/questions/49467932/dividing-city-by-longitude-and-latitude-into-matrix)
NW = (30.430086,-97.841059)
NE =(30.376194,-97.605366)
SW = (30.193961,-97.915296)
SE = (30.186333,-97.692742)
df = pd.DataFrame()
cols = np.linspace(SW[1], SE[1], num=60)
rows = np.linspace(SW[0], NW[0], num=60)
coords = list(zip(rows,cols))
xx, yy = np.meshgrid(rows,cols)
# Google Place API Stuff
# Resources for this section:
# https://youtu.be/ckPEY2KppHc
# https://github.com/codingforentrepreneurs/30-Days-of-Python/blob/master/tutorial-reference/Day%2020/Geocoding%20%26%20Places%20API%20with%20Google%20Maps.ipynb
api_key = #put your API key here
base_endpoint_places = "https://maps.googleapis.com/maps/api/place/findplacefromtext/json"
params = {
"key": api_key,
"input": "Coffee",
"inputtype": "textquery",
"fields": "formatted_address,name,geometry"
}
final_data = []
for coordinates in coords:
lat, lng = coordinates
locationbias = f"point:{lat},{lng}"
use_cirular = True
if use_cirular:
radius = 1000
locationbias = f"circle:{radius}@{lat},{lng}"
params['locationbias'] = locationbias
params_encoded = urlencode(params)
places_endpoint = f"{base_endpoint_places}?{params_encoded}"
# print(places_endpoint)
r = requests.get(places_endpoint)
jj = json.loads(r.text)
results = jj['candidates']
for result in results:
# print(result)
name = result['name']
lat = result['geometry']['location']['lat']
lng = result['geometry']['location']['lng']
data = [name, lat, lng]
final_data.append(data)
labels = ['Place Name','Latitude', 'Longitude', ]
export_dataframe= pd.DataFrame.from_records(final_data, columns=labels)
export_dataframe.to_csv('export_dataframe.csv')
# this code only returns 20 results, see: https://stackoverflow.com/questions/9614258/how-to-get-20-result-from-google-places-api
class GoogleMapsClient(object):
lat = None
lng = None
data_type = 'json'
location_query = None
api_key = None
def __init__(self, api_key=None, address_or_postal_code=None, *args, **kwargs):
super().__init__(*args, **kwargs)
if api_key == None:
raise Exception("API key is required")
self.api_key = api_key
self.location_query = address_or_postal_code
if self.location_query != None:
self.extract_lat_lng()
def extract_lat_lng(self, location=None):
loc_query = self.location_query
if location != None:
loc_query = location
endpoint = f"https://maps.googleapis.com/maps/api/geocode/{self.data_type}"
params = {"address": loc_query, "key": self.api_key}
url_params = urlencode(params)
url = f"{endpoint}?{url_params}"
r = requests.get(url)
if r.status_code not in range(200, 299):
return {}
latlng = {}
try:
latlng = r.json()['results'][0]['geometry']['location']
except:
pass
lat,lng = latlng.get("lat"), latlng.get("lng")
self.lat = lat
self.lng = lng
return lat, lng
def search(self, keyword="Mexican food", radius=5000, location=None):
lat, lng = self.lat, self.lng
if location != None:
lat, lng = self.extract_lat_lng(location=location)
endpoint = f"https://maps.googleapis.com/maps/api/place/nearbysearch/{self.data_type}"
params = {
"key": self.api_key,
"location": f"{lat},{lng}",
"radius": radius,
"keyword": keyword
}
params_encoded = urlencode(params)
places_url = f"{endpoint}?{params_encoded}"
r = requests.get(places_url)
# print(places_url, r.text)
if r.status_code not in range(200, 299):
return {}
return r.json()
def detail(self, place_id="ChIJlXOKcDC3j4ARzal-5j-p-FY", fields=["name", "rating", "formatted_phone_number", "formatted_address"]):
detail_base_endpoint = f"https://maps.googleapis.com/maps/api/place/details/{self.data_type}"
detail_params = {
"place_id": f"{place_id}",
"fields" : ",".join(fields),
"key": self.api_key
}
detail_params_encoded = urlencode(detail_params)
detail_url = f"{detail_base_endpoint}?{detail_params_encoded}"
r = requests.get(detail_url)
if r.status_code not in range(200, 299):
return {}
return r.json()
client = GoogleMapsClient(api_key=GOOGLE_API_KEY, address_or_postal_code='78757')
# print(client.lat, client.lng)
client.search("Coffee", radius=500)