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

Leave a Reply

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

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

Close

Meta