Digital resources in the Social Sciences and Humanities OpenEdition Our platforms OpenEdition Books OpenEdition Journals Hypotheses Calenda Libraries OpenEdition Freemium Follow us

Python und Geonames-API zur Geokodierung historischer Ortsnamen

Automatisierte Geocodierung im DigiKAR Projekt

In diesem Beitrag stelle ich vor, wie im DigiKAR-Projekt Python und die Geonames-API genutzt werden, um historische Ortsnamen mit Geodaten zu verbinden. Die Geonames-API ist eine Internetschnittstelle, über die die in Geonames gesammelten Ortsinformationen sowie Längen- und Breitengrade via Skript abgerufen werden können. Dazu verwenden wir in DigiKAR Python-Skripte, die derzeit auf dem Daten- und Software-Server der Universität Maastricht laufen. Python kann jedoch auch lokal auf dem Computer installiert werden, um die Skripte auszuführen.

In DigiKAR, das Ortsdaten aus dem Heiligen Römischen Reich modelliert und visualisiert, werden Ortsnamen aus verschiedenen historischen Quellen und Forschungsarbeiten, wie den Rekonstruktionen der Mainzer Universitätsmatrikel, extrahiert und auf moderne Ortsnamen abgebildet, um mit modernen Geo-APIs zumindest eine erste Grundlage für die digitale Kartenarbeit zu schaffen. Im Mainzer Teilprojekt ist dies möglich, weil uns vor allem die Stadtebene interessiert und Lage kleinerer Einheiten nicht visualisiert wird. Eine der Hauptherausforderungen besteht allerdings darin, dass unsere Ortsdaten oft in lateinischer Sprache vorliegen oder alte Schreibweisen verwenden. Daher wurden zunächst alle Ortsnamen extrahiert, wie sie in den Quellen vorkommen, und dann manuell auf heutige Ortsnamen gemappt. Diese neuen Ortsnamen werden automatisiert mit Geonames einem bestimmten geogaphischen Ort zugewiesen, aber auch durch menschliche Editoren korrigiert. Obwohl menschliche Intervention erforderlich ist, spart die automatisierte Geokodierung bei tausenden Ortsnamen erheblich Zeit und erlaubt eine iterative Datenverbesserung durch Testvisualisierungen.

Im DigiKAR-Arbeitspaket 3, das sich mit Kurmainz beschäftigt, spielen Orte im heutigen Hessen und Rheinland-Pfalz eine besondere Rolle, aber auch Orte im Eichsfeld und in der Region Erfurt kommen wegen der historischen Verbindungen in unseren Daten vor. Aufgrund der Mobilität der betroffenen Personen erstreckt sich die Recherche auch bis nach Böhmen, Italien und England. Mehrere tausend Orte wurden bereits zu Projektbeginn mit Google und Geonames geokodiert, um durch den Vergleich der beiden APIs zu guten Egebnissen zu kommen. In der letzten Projektphase tragen wir kleinere Listen neuer Ortsnamen nach, für die Geodaten benötigt werden. Hier konzentrieren wir uns auf die Arbeit mit Geonames, da uns diese API in Bezug auf Orte in Europa zuverlässiger erscheint als Google. Leider ergeben sich bei der Arbeit mit Geonames auch besondere Herausforderungen, die ich gleich zu Beginnen benennen möchte.

Herausforderungen in der Arbeit mit der Geonames API

In seiner Doktorarbeit Geographically Constrained Information Retrieval (Universität Groningen, 2010) hat Geoffrey Andogah bemerkt, dass eine “intelligente”, d.h. am Forschungkontext orientierte, Auswahl geographischer Ergebnisse z.B. in der automatisierten Identifikation von Geodaten für circa ein Fünftel der Nutzenden sehr relevant ist, aber oft die Fähigkeiten der verfügbaren Dienste übersteigt:

Eighteen percent of information seekers demand geographically intelligent information retrieval systems (Sanderson and Kohler, 2004). State-of-the-art information retrieval (IR) systems lack the geographical intelligence needed to effectively answer geography-dependent questions.

Fast fünfzehn Jahre später hat sich die Situation nur bedingt verbessert. Während zukünftig sicherlich Künstliche Intelligenz zu einer Verbesserung von Geocoding und Named Entity Recognition für individuelle Projekte beitragen kann, werden mehrere mögliche Ergebnisse etwa in der Geonames API derzeit noch nach festen Kriterien priorisiert, die man nur bedingt beeinflussen kann. Relevance ranking, und vor allem “non-geographic relevance ranking” (Andogah, p. 135ff.) sind deshalb weiterhin eine große Herausforderungen, die menschliche Kontrolle automatisierter Ergebnisse notwendig macht.

Wenn man die Geonames API über ein Skript (in unserem Fall Python) nutzt, kann man bestimmten Geonames Parametern verschiedene sogenannte Argumente zuweisen, um Suchergebnisse einzuschränken. Wie ich später noch erläutere, sind hier die via featureClassdefinierten Ortstypen die wichtigste Möglichkeit, um z.B. eine Suche allein auf Städte, Gewässer, Gebäude etc. einzuschränken und im Gegenzug andere Ortstypen zu ignorieren. Innerhalb einer featureClass aber priorisiert die API selbst, welcher Ort der wahrscheinlichste ist. Die Priorisierung beruht dabei auf einem komplexen Algorithmus, der in der Dokumentation nicht explizit erklärt wird, und deshalb wohl für die meisten Nutzenden unverständlich bleibt. Auch die Annahmen, die ich hier formuliere, beruhen weitgehend auf meinen eigenen Beobachtungen zum Verhalten der API sowie auf Rückschlüssen aus den Parametern, die man laut API Dokumentation selbst in der Abfrage definieren kann.

Ein erstes Problem, das sich uns häufig stellte, war, dass die API nicht-exakte Übereinstimmungen des Ortsnamens priorisierte, auch wenn ein Eintrag zum exakten Treffer vorhanden war. Ein Beispiel ist der Ort “Gmünd” in Österreich, für den wir die Geodaten von “Schwäbisch Gmünd” in Baden-Württemberg bekamen. Sucht man “Gmünd” auf der geonames.org Webseite, sieht man in der Tat, dass “Schwäbisch Gmünd” in featureClass = P ganz oben steht:

https://www.geonames.org/search.html?q=Gm%C3%BCnd&country=

Dieses Verhalten, das wir auch in anderen Fällen beobachteten, legt nahe, dass oft andere Ranking Kriterien bevorzugt werden. Diese können sein:

  • Häufigkeit des Ortes in früheren Nutzerabfragen
  • Einwohnerzahl des Ortes (heute)
  • Bevölkerungsdichte des Ortes (heute)
  • Administrative Bedeutung des Ortes (heute), z.B. Rolle als Hauptstadt einer Region oder eines Landes
  • Administrative Hierarchie (z.B. Gesamtort vor Ortsteil)

Deshalb ist es wichtig, die nutzerdefinierten Parameter zu verstehen und so weit als möglich zu nutzen. Für die weitere Einschränkung der Suchergebnisse über Ortstypen hinaus sind besonders der MaxRows Parameter zur numerischen Begrenzung der Treffer und der OrderBy Parameter zur Sortierung der Treffer hilfreich. Allerdings gilt auch hier, dass die Sortierung keinen komplexen logischen Vorgaben etwa aus narrativen Zusammenhängen folgen kann, sondern auf numerisch ausdrückbaren Kriterien wie Bevölkerungszahl, Abstand zu einem anderen Ort etc. beruhen muss. In diese Richtung geht auch die Option, mit der sog. Geographical Proximity (zu einem Punkt mit Koordination) zu arbeiten. Diese Methode wird besonders beim sog. reverse geocoding genutzt.

Es ist auch möglich, den lang Parameter oder countryBias zu nutzen, um Treffer in der eigenen Sprache oder in einem bestimmten Land zu priorisieren, aber das hilft in Projekten, die sich wie DigiKAR zwar vorrangig auf den deutschen Raum beschränken, aber auch Daten aus dem Rest Europas verarbeiten, nicht weiter. Gerade in der Arbeit mit historischen Orten, deren Stellenwert in der Vergangenheit ein anderer war, kann dies zu Problemen bei der automatisierten Zuweisung der Ortsdaten führen.

Systematische Integration mehrerer Parameter in Geodocing Skripte: Abfrage mehrerer Feature Classes

Seit Juni 2024 habe ich unser erstes Geocoding Skript aus dem Jahr 2022 nochmals erweitert, um mehrere Ortstypen (sog. feature classes) in Geonames abzufragen und zudem nur einen Teil des Eingabestrings (oft eine Regioneninformation) zu erfassen, wenn im ersten Versuch mit komplexen Ortsinformatonen kein konkreter Ort gefunden wurde.

Geocoding mit Python & Geonames – Tipps zur Fehlerreduktion in der automatisierten Ortsnamenszuweisung

In der ersten Sektion des Skripts werden Pakete installiert, die nicht zur Standarddistribution von Python gehören, um sie dann im weiteren Verlauf des Skripts zu importieren und zu benutzen. Besonders wichtig sind dabei das Paket Geocoder, das die Kommunikation mit Geonames ermöglicht, und das Basemap-Paket, ein visuelles Mapping-Tool.

Das Skript beginnt mit der Installation der Pakete und dem Upgrade des PIP-Pakets (nur notwendig im speziellen Fall der Maastrichter Umgebung). Danach werden Pandas, eine Bibliothek zur Bearbeitung von Tabellendaten, und der Geocoder importiert, um eine Excel-Tabelle mit den fehlenden Ortsnamen zu bearbeiten. Diese Tabelle enthält im Beispiel aus DigiKAR 311 Zeilen mit Ortsnamen aus verschiedenen europäischen Ländern. Die linke Spalte zeigt die Originalbezeichnungen in den Quellen, während die rechte Spalte das Mapping auf neue Ortsnamen enthält. Der Geocoder geht die Ortsnamen durch, um zu überprüfen, ob ein Treffer in Geonames gefunden wird. Wir verwendung zuerst die Feature-Class P für Populated Places. Falls ein Ort wie “Hesselbach, Odenwald” nicht gefunden wird, sucht das Skript nach dem größeren Gebiet. Danach versucht das Skript bei Bedarf Ergebnisse in weiteren Feature-Classes wie S zu finden. Eine if-elif-else-Kondition im Skript überprüft zuerst den kompletten Ortsnamen, dann das Gebiet und gibt im Zweifel “unbekannt” aus. Um Fehler zu vermeiden beschränken wir unsere Suche zudem auf Europa. Wir möchten Verwechslungen mit gleichnamigen Orten außerhalb Europas verhindern, da in DigiKAR nur europäische Orte relevant sind.

Nachdem das Skript alle Ortsnamen geokodiert hat, zeigt es die neuen Geoinformationen in einer neuen Tabelle an, die auch in eine neue Datei geschrieben werden kann. Eine kritische Überprüfung der Daten durch Kollegen ist jedoch weiterhin notwendig, um sicherzustellen, dass die richtigen Orte gewählt wurden. Besonders auffällig sind im Beispiel negative Breitenangaben, die auf westliche Längengrade und hier konkret auf einen Ort im Vereinigten Königreich hinweisen. In weiteres Quellenstudium ist nowendig, um zu entscheiden, wie realistisch diese Zuweisungen jeweils sind.

Zudem ist die kostenfreie Version der Geonames API leider auf 1000 Server-Anfragen pro Stunde begrenzt. Daten kann man dann in kleinen Paketen geokodieren und im Python Skript einen Timer einbauen, der die Funktion zur Geokodierung nur alle 3600 Sekunden startet, aber dieser Prozess kann wiederum in einem Timeout seitens des Notebook-Servers fuhren, wenn man z.B. via VPN auf einer virtuellen Maschine einer Forschungseinrichtung arbeitet. Das Geonames Abonnement, mit dem man große Anfragen stellen kann, ist leider vergleichsweise teuer und nicht fur alle Forschenden erschwinglich.

Obwohl Ergebnisse fur viele europaische und “historische” Orte in Google unserer Erfahrung nach weniger brauchbar sind als in Geonames, kann man in Fallen, in denen sehr viele Ortsdaten schnell geokodiert werden sollen, deshalb auch auf die Google API ausweichen, die ein hoheres tagliches Rate Limite hat und zudem fur individuelle Nutzer gunstiger ist.

Das Geocoding mit der Google API beschreibe ich in englischer Sprache in meinem Blogpost “Geocoding with Google API in Python and Interactive Mapping with ipyleaflet”.

Priorisierung exakter String-Matches

[Add new script!!]


OpenEdition suggests that you cite this post as follows:
Monika Barget (July 1, 2024). Python und Geonames-API zur Geokodierung historischer Ortsnamen. INSULAE. Retrieved February 6, 2025 from https://doi.org/10.58079/11x8h


Monika Barget

Monika Barget is an assistant professor in History at Maastricht University and co-coordinator of the DigiKAR geohumanities project at IEG Mainz. Her research interests include spatial history, digital mapping, political history and media.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

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