Created
May 5, 2021 11:28
-
-
Save geblanco/28b03aed8c59f72aa22e3c6d39ca4036 to your computer and use it in GitHub Desktop.
Simple script to paint in an interactive map a set of addreses from a csv file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# !pip install requests urllib3 geopy pandas folium | |
# partially taken from: | |
# https://towardsdatascience.com/pythons-geocoding-convert-a-list-of-addresses-into-a-map-f522ef513fd6\ | |
import requests | |
import json | |
import urllib | |
from geopy.geocoders import Nominatim, GoogleV3 | |
import pandas as pd | |
import folium | |
from folium.plugins import MarkerCluster | |
from pathlib import Path | |
# MapQuest is also avialable in geocoders, it's free. | |
# Requires signup to get an API key | |
base_url= "https://maps.googleapis.com/maps/api/geocode/json?" | |
AUTH_KEY = "<PUT YOUR TOKEN HERE>" | |
geolocator = GoogleV3(api_key=AUTH_KEY) | |
# just a test | |
# parameters = {"address": "Tuscany, Italy", "key": AUTH_KEY} | |
# print(f"{base_url}{urllib.parse.urlencode(parameters)}") | |
# r = requests.get(f"{base_url}{urllib.parse.urlencode(parameters)}") | |
# data = json.loads(r.content) | |
# data | |
# data file | |
data_file = "./oficinas_registro.csv" | |
# data with geolocalization data | |
geoloc_processed_file = "./oficinas_registro_geoloc.csv" | |
# output map file | |
map_file = "./oficinas_registro_map.html" | |
popup_field = "DENOMINACION OFICINA DE REGISTRO" | |
tooltip_field = "DENOMINACION OFICINA DE REGISTRO" | |
# Preprocess data to get addresses field | |
def add_address_field(data): | |
data["address"] = \ | |
data[["TIPO VIA","NOMBRE VIA"]]\ | |
.dropna(axis=1)\ | |
.astype(str)\ | |
.agg(" ".join, axis=1) + \ | |
data[["N? VIA","CP","RESTO DIRECCION","LOCALIDAD","PROVINCIA","ISLA","COMUNIDAD AUTONOMA"]]\ | |
.dropna(axis=1)\ | |
.astype(str)\ | |
.agg(", ".join, axis=1) | |
return data | |
# Add geolocalization data, requires API KEY | |
def apply_geoloc(data, geolocator): | |
data["loc"] = data["address"].apply(geolocator.geocode) | |
data["point"] = data["loc"].apply( | |
lambda loc: tuple(loc.point) if loc else None | |
) | |
data[["lat", "lon", "altitude"]] = pd.DataFrame( | |
data["point"].to_list(), index=data.index | |
) | |
return data | |
def load_data(geoloc_processed_file, data_file, geolocator): | |
if Path(geoloc_processed_file).exists(): | |
data = pd.read_csv(geoloc_processed_file) | |
else: | |
data = add_address_field(pd.read_csv(data_file)) | |
data = apply_geoloc(data, geolocator) | |
data.to_csv(geoloc_processed_file) | |
return data | |
def build_map(data, popup_field, tooltip_field): | |
# center to the mean of all points | |
m = folium.Map(location=data[["lat", "lon"]].mean().to_list(), zoom_start=2) | |
# if the points are too close to each other, cluster them, create a cluster overlay with MarkerCluster | |
marker_cluster = MarkerCluster().add_to(m) | |
# draw the markers and assign popup and hover texts | |
# add the markers the the cluster layers so that they are automatically clustered | |
for i,r in data.iterrows(): | |
location = (r["lat"], r["lon"]) | |
folium.Marker( | |
location=location, | |
popup = r[popup_field], | |
tooltip=r[tooltip_field] | |
).add_to(marker_cluster) | |
return m | |
data = load_data(geoloc_processed_file, data_file, geolocator) | |
m = build_map(data, popup_field, tooltip_field) | |
m.save(map_file) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment