Tilføj flere geokodede kortmarkører med Geopy og Folium i Python

I et tidligere indlæg har jeg allerede demonstreret brugen af Nominatim i Python (ved hjælp af Geopy-modulet) til geokodning af lokationer til længde- og breddegradskoordinater.

I dette indlæg vil jeg vise hvordan man kan geokode en liste med placeringer ved hjælp af Geopy. Jeg vil desuden oprette et kort med flere markører, én for hver placering i min oprindelige dataramme.

Jeg vil starte med at bruge Pandas-modulet til at indlæse en enkel og kort csv-fil. Filen indeholder placeringer med beskrivelse af land, by og en gadenavn:

# importer pandas
import pandas
# læs i csv-fil indeholdende placeringsdata
data = pandas.read_csv("locations.csv")
# vis datarammen med data fra csv-filen
data
countrycitystreetmetric
0GermanyBerlinAlexanderplatz 110
1GermanyBerlinDircksenstrasse 25
2GermanyBerlinRathausstrasse 116

Lad os kontrollere indholdet af datatypen for datarammen:

type(data)
pandas.core.frame.DataFrame

Nu hvor jeg har indlæst alle relevante data vil jeg geokode placeringerne og tildele dem geokodede koordinater i en ny kolonne. Da alle data er indlæst i from af en pandas DataFrame kan jeg gøre brug af metoden Apply() for at anvende den relevante Nominatim-geokodningstjeneste på hver adresse i datarammen.

Først skal jeg konvertere alle kolonneindlæg til adresser og tilføje dem til en ny kolonne i tabellen DataFrame. Derefter kan jeg oprette et serviceobjekt, der henviser til Nominatim Geopy-tjenesten og anvende denne service på alle placeringer. Jeg skal så returnere det geokodede resultat i en ny ekstra kolonne:

# sammenfletning af land, by og gade i en enkelt adressestreng
data["addresses"] = data["country"] + ", " + data["city"] + ", " + data["street "]
# import af geopy-modulet
import geopy
# opret et serviceobjekt
service = geopy.Nominatim(user_agent = "myGeocoder")
# geokode hver adresse ved hjælp af .apply () -metode til pandas DataFrame
from geopy.extra.rate_limiter import RateLimiter
data["coordinates"] = data["addresses"].apply(RateLimiter(service.geocode,min_delay_seconds=1))
# vis tabeldata
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…

Lad os kontrollere datatypen i kolonnespalten “coordinates”:

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

De geokodede placeringer er af typen Geopy Location. Objekter i placeringsklassen har forskellige attributter. En af dem er breddegrad og en anden er længdegrad:

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

Jeg beregner nu den “gennemsnitlige” længde- og breddegradsscore. Jeg vil bruge dem som centerpunkt på mit Folium-placeringsmarkørkortplot:

# udpakning af længde- og breddegradsværdier til separate lister
longs = [coord.longitude for coord in data["coordinates"]]
lats = [coord.latitude for coord in data["coordinates"]]
# beregning af gennemsnitlige længde- og breddegradsværdier
import statistics
meanLong = statistics.mean(longs)
meanLat = statistics.mean(lats)
# display resultat
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]]

Ved hjælp af Folium-modulet kan jeg nu oprette markører til placeringerne og plotte dem på kortet:

# importer folium modulet
import folium
# opret et basiskort centreret omkring Berlin
mapObj = folium.Map(location = [meanLat,meanLong], zoom_start = 15)
# opret markørobjekt til Berlin, en efter en for hver placering i data DataFrame
for i in range(0,data.shape[0]): # .shape [0] for Pandas DataFrame er antallet af rækker
    # opret markør for placering i 
    markerObj = folium.Marker(location = [lats[i],longs[i]])
    # tilføj markør til kort
    markerObj.add_to(mapObj)
# vis kort
mapObj

You May Also Like

Leave a Reply

Leave a Reply

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *

This site uses Akismet to reduce spam. Learn how your comment data is processed.