Mehrere geokodierte Kartenmarkierungen mit Geopy und Folium in Python

In einem früheren Beitrag habe ich bereits gezeigt wie Nominatim in Python (mithilfe des Geopy-Moduls) verwendet wird um einen Standortnamen in Längen- und Breitengradkoordinaten zu geokodieren.

In diesem Beitrag möchte ich zeigen wie man mit Geopy eine Liste von Orten geokodieren kann.

Zu diesem Zweck verwende ich zunächst das Pandas-Modul zum Einlesen einer einfachen und kurzen CSV-Datei mit Standortnamen. Standorte werden durch Einträge in einer Land-, Stadt- und Straßenspalte angegeben:

# importiere pandas
import pandas
# lese csv Datei mit den Standorten ein
data = pandas.read_csv("locations.csv")
# zeige inhalt des Datenrahmens an
data
countrycitystreetmetric
0GermanyBerlinAlexanderplatz 110
1GermanyBerlinDircksenstrasse 25
2GermanyBerlinRathausstrasse 116
Überprüfen wir nun den Datentyp der Datentabelle:
type(data)
pandas.core.frame.DataFrame

Nachdem ich die Daten eingelesen habe werde ich die Standorte geokodieren und einer neuen Spalte geokodierte Koordinaten zuweisen. Da es sich bei den Daten um einen Pandas-DataFrame handelt, kann ich die Methode apply () verwenden, um den entsprechenden Nominatim-Geokodierungsdienst auf jede Adresse im Datenrahmen anzuwenden.

Zuerst muss ich alle Spalteneinträge in Adressen konvergieren und diese in eine neue Spalte im tabellarischen DataFrame einfügen. Anschließend kann ich ein Dienstobjekt erstellen, das auf den Nominatim Geopy-Dienst verweist, und diesen Dienst auf jeden Standort anwenden, wobei das geokodierte Ergebnis in einer zusätzlichen neuen Spalte zurückgegeben wird:

# Zusammenführen von Land, Stadt und Straße zu einer einzigen Adresszeichenfolge
data["addresses"] = data["country"] + ", " + data["city"] + ", " + data["street "]
# Importieren Sie das Geopy-Modul
import geopy
# ein Serviceobjekt erstellen
service = geopy.Nominatim(user_agent = "myGeocoder")
# Geocodieren Sie jede Adresse mit der Methode .apply () für Pandas DataFrame
from geopy.extra.rate_limiter import RateLimiter
data["coordinates"] = data["addresses"].apply(RateLimiter(service.geocode,min_delay_seconds=1))
# Tabellendaten anzeigen
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…

Lassen Sie uns den Datentyp der Spalteneinträge „coordinates“ überprüfen:

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

Die geokodierten Standorte sind vom Typ Geopy Location. Objekte der Location-Klasse besitzen verschiedene Attribute. Einer davon ist der Breitengrad und der andere der Längengrad:

data["coordinates"][0].longitude
13.4144809
data["coordinates"][0].latitude
52.5228654

Ich berechne jetzt die „mittleren“ Längen- und Breitengrade. Ich möchte sie als Mittelpunkt meines Folium-Positionsmarkierungs-Kartenplots verwenden:

# Extrahieren von Längen- und Breitengraden in separate Listen
longs = [coord.longitude for coord in data["coordinates"]]
lats = [coord.latitude for coord in data["coordinates"]]
# Berechnung der mittleren Längen- und Breitengrade
import statistics
meanLong = statistics.mean(longs)
meanLat = statistics.mean(lats)
# Ergebnis anzeigen
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]]

Mit dem Folium-Modul kann ich jetzt Markierungen für die Standorte erstellen und diese auf Kartenkacheln zeichnen:

# importiere Folium
import folium
# erstelle Grundkarte mit Zentrum in Berlin
mapObj = folium.Map(location = [meanLat,meanLong], zoom_start = 15)
# Erstelle eine Markierung nach der anderen
for i in range(0,data.shape[0]):
    markerObj = folium.Marker(location = [lats[i],longs[i]])
    markerObj.add_to(mapObj)
# zeige Karte an
mapObj

You May Also Like

Leave a Reply

Leave a Reply

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.