Múltiples marcadores de mapas geocodificados con Geopy y Folium en Python

En un post anterior ya demostré cómo usar Nominatim en Python (usando el módulo Geopy) para geocodificar un nombre de ubicación en coordenadas de longitud y latitud.

En este post quiero mostrar cómo se puede geocodificar una lista de localizaciones utilizando Geopy.

Para ello, empezaré utilizando el módulo Pandas para leer un simple y breve archivo csv que contiene nombres de lugares especificados por entradas en una columna de país, ciudad y calle:

# importando pandas
import pandas
# leer el archivo csv que contiene los datos de localización
data = pandas.read_csv("locations.csv")
# mostrar la tabla del archivo csv
data
countrycitystreetmetric
0GermanyBerlinAlexanderplatz 110
1GermanyBerlinDircksenstrasse 25
2GermanyBerlinRathausstrasse 116

Comprobemos el tipo de dato de los datos tabulares:

type(data)
pandas.core.frame.DataFrame

Ahora que he leído los datos voy a geocodificar las localizaciones y asignar los coordiantes geocodificados a una nueva columna. Como los datos son un DataFrame de pandas, puedo hacer uso del método apply() para aplicar el servicio de geocodificación de Nominatim correspondiente a cada dirección del dataframe.

Primero tengo que convertir todas las entradas de la columna en direcciones, añadiendo éstas en una nueva columna en el DataFrame tabular. A continuación, puedo crear un objeto de servicio que haga referencia al servicio Geopy de Nominatim y aplicar ese servicio a cada ubicación, devolviendo el resultado geocodificado en una nueva columna adicional:

# fusionar el país, la ciudad y la calle en una sola cadena de direcciones
data["addresses"] = data["country"] + ", " + data["city"] + ", " + data["street "]
# importar el módulo geopy
import geopy
# crear un objeto de servicio
service = geopy.Nominatim(user_agent = "myGeocoder")
# geocodificar cada dirección, utilizando el método .apply() para pandas DataFrame
from geopy.extra.rate_limiter import RateLimiter
data["coordinates"] = data["addresses"].apply(RateLimiter(service.geocode,min_delay_seconds=1))
# mostrar datos tabulares
data
countrycitystreetmetricaddressescoordinates
0GermanyBerlinAlexanderplatz 110Germany, Berlin, Alexanderplatz 1(Alexanderstraße, Spandauer Vorstadt, Mitte, B…
1GermanyBerlinDircksenstrasse 25Germany, Berlin, Dircksenstrasse 2(2, Dircksenstraße, Luisenstadt, Mitte, Berlin…
2GermanyBerlinRathausstrasse 116Germany, Berlin, Rathausstrasse 1(1-14, Rathausstraße, Spandauer Vorstadt, Mitt…

Comprobemos el tipo de datos de las entradas de la columna «coordinates»:

type(data["coordinates"][0])
geopy.location.Location

Comprobemos el tipo de datos de las entradas de la columna «coordenadas»:

data[«coordenadas»][0].longitud

13.4144809

datos[«coordenadas»][0].latitud

52.5228654

Ahora calculo las puntuaciones «medias» de longitud y latitud. Quiero utilizarlos como punto central de mi mapa de marcadores de ubicación Folium:

# extrayendo los valores de longitud y latitud a listas separadas
longs = [coord.longitude for coord in data["coordinates"]]
lats = [coord.latitude for coord in data["coordinates"]]
# calcular los valores medios de longitud y latitud
import statistics
meanLong = statistics.mean(longs)
meanLat = statistics.mean(lats)
# mostrar el resultado
print("meanLong = " + str(meanLong) + "; meanLat = " + str(meanLat))
meanLong = 13.412910038576356; meanLat = 52.52100943333333
[longs,lats]
[[13.4144809, 13.4136431, 13.410606115729072],
 [52.5228654, 52.5208149, 52.519348]]

Utilizando el módulo Folium, ahora puedo crear marcadores para las localizaciones y trazarlas en los mosaicos del mapa:

# import folium
import folium
# crear un mapa base centrado en Berlín
mapObj = folium.Map(location = [meanLat,meanLong], zoom_start = 15)
# crear objeto marcador para Berlín, uno por uno para cada ubicación en los datos DataFrame
for i in range(0,data.shape[0]): # .shape[0] for Pandas DataFrame is the number of rows
    # crear un marcador para el lugar i
    markerObj = folium.Marker(location = [lats[i],longs[i]])
    # añadir marcador al mapa
    markerObj.add_to(mapObj)
# mostrar mapa
mapObj

You May Also Like

Leave a Reply

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.