Seit ein paar Wochen finden Besucher von luki.org eine Karte mit den ungefähren Wohnorten der LUKi-Mitglieder und den Orten bisheriger LUKi-Treffen auf Basis von OpenStreetMap. Für Vereinsmitglieder gibt es mittlerweile zusätzlich eine Karte, die zu den Mitgliedern auch die Namen anzeigt.
Dieser Blog-Beitrag beschreibt, wie es dazu kam und wie die Umsetzung erfolgte. Der resultierende Code ist im LUKi-Repo auf GitHub zu finden. Eine Karte mit Wohnorten der Mitglieder und Orten der Vereinstreffen gab es bereits zuvor — allerdings auf Basis von Google Maps. Für einen LUKi natürlich kein befriedigender Zustand, zumal es mit OpenStreetMap einen freien Kartenanbieter gibt. Es war also klar, dass hier etwas getan werden musste.
Schnell war ein OSM-Plugin für WordPress gefunden. Dieses verfügt mittels Dateien im KML-Format über die Möglichkeit, eigene Daten in die Karte einzubinden. Ein paar Experimente zeigten, dass dies ein gangbarer Weg ist. Nun stellte sich die Frage, wie die gewünschten Daten auf die Karte bzw. in die KML-Datei kommen. Dabei sollte gewährleistet sein, dass bei Änderungen ohne viel Aufwand eine neue KML-Datei erzeugt werden kann. Außerdem sollte es nicht notwendig sein, dass die Mitgliederliste das System des Vorstands verlassen muss. Zusätzlich sollte jedes Mitglied selbst entscheiden können, ob der eigene, ungefähre Wohnort auf der Karte angezeigt wird.
Aus diesen Anforderungen entwickelte sich folgende Idee: Die im ODS-Format vorliegende Mitgliederliste wird um eine Spalte erweitert, welche die Einverständnis anzeigt. Ein Skript kann diese dann auswerten und die Postleitzahlen der Mitglieder mit Einverständnis ausgeben. Den PLZ werden dann im nächsten Schritt mittels Geo-Lookup per Nominatim Koordinaten zugeordnet. Die Koordinaten werden schließlich in geeigneter Form in eine KML-Datei geschrieben. Zu kombinieren war dies mit den Orten der LUKi-Treffen.
Während der Umsetzung kam noch der Vorschlag eines LUKis zusätzlich eine interne Karte anzubieten, die nur für Mitglieder des Vereins zugänglich ist und zu den Mitgliedern die Namen anzeigt. Dieser Vorschlag wurde natürlich aufgegriffen und bei der Umsetzung berücksichtigt. So gibt es in der Mitgliederliste nun zwei zusätzliche Spalten: die eine zeigt das Einverständnis für die öffentliche, die andere das Einverständnis für die vereinsinterne Karte. Bei der Extraktion wird zwischen öffentlicher und interner Karte unterschieden. Im zweiten Fall wird zur PLZ auch der Name ausgegeben, ansonsten wird als Name schlicht “Mitglied” ausgegeben. So liegen die Daten zur KML-Erstellung, unabhängig ob öffentlich oder intern, in der gleichen Form (CSV) vor und können identisch verarbeitet werden — einziger Unterschied: Bei der öffentlichen Karte wird, sollten zwei oder mehr LUKis die gleiche PLZ haben statt “Mitglied” “n Mitglieder” angezeigt. Die CSV-Daten können kombiniert werden mit CSV-Daten der LUKi-Treffen, welche in gleicher Form vorliegen. Zur Unterscheidung, ob Mitglied oder LUKi-Treffen, wird eine zusätzliche Spalte verwendet.
Realisiert ist dies in zwei verschiedenen Python-Skripten, so dass die Extraktion der Daten und die Erstellung der KML-Datei theoretisch auf verschiedenen Systemen erfolgen könnte. Damit bei Neugenerierung der KML-Datei bereits durchgeführte Geo-Lookups nicht wiederholt werden müssen, werden diese in einer zusätzlichen Datei gespeichert.
Nachdem dann alle LUKis, um ihr Einverständnis gefragt wurden, konnte die öffentliche Karte schließlich online gehen. Für die interne Karte musste noch sichergestellt werden, dass die zugehörige WordPress-Seite und insbesondere die KML-Datei nur für Mitglieder zugänglich ist. Für Letzteres ist nun ein PHP-Skript ähnlich zu diesem im Einsatz. Es wird jedoch zusätzlich geprüft, ob dem zugreifenden Nutzer die zu diesem Zweck angelegte Rolle “Mitglied” zugewiesen ist. Das Plugin If Menu sorgt dafür, dass ein Menüeintrag zur Seite mit der internen Karte nur Nutzern mit dieser Rolle angezeigt wird.
Nun musste noch jedem Mitglied die Rolle zugewiesen werden. Damit dies nicht händisch mit dem WordPress-Plugin Members gemacht werden muss, hat Johannes ein PHP-Skript geschrieben, welches dies über die WordPress-API erledigt. Als Eingabe dient dabei die Liste der E-Mail-Adressen der Vereinsmitglieder. Das Skript sucht dann zu jeder E-Mail-Adresse den zugehörigen Account in WordPress. Ist ein solcher vorhanden, wird, sofern noch nicht geschehen, die Rolle zugewiesen. Das Skript wird per SSH gestartet und E-Mail-Adressen per Pipe übertragen und vom Skript dann von STDIN gelesen.
Wer sich den Code der oben beschriebenen Python-Skripte anschauen möchte oder vielleicht ein ähnliches Problem zu lösen hat, findet diese wie eingangs erwähnt auf GitHub.
Known Issues:
Die Skripte (und die Mitgliederliste) sind momentan darauf ausgelegt, dass alle LUKi-Mitglieder in Deutschland leben. Für LUKis ist es daher fortan untersagt, ins Ausland zu ziehen. Scherz beiseite: Natürlich werden wir im Fall des Falles geeignete Maßnahmen ergreifen, welche nicht den Vereinsauschluss beinhalten 😉
Vielen Dank für diesen Beitrag!
Ich versuche gerade, das für meine Zwecke anzupassen, scheitere aber (unter anderem) daran, dass mir nicht ganz klar ist, welche Spalten eure Mitgliederliste hat. Könntet ihr da etwas Licht reinbringen? Habe leider auch so gar keine Ahnung von Python, daher fällt es mir schwer, das aus den Skripten rauszulesen.
Hallo Lennart. Im Skript https://github.com/luki-ev/membermap/blob/master/extract-data.py findest du die Spaltennamen beim Zugriff auf “row” (Zeilen 21-22 und 26-27). Beispielsweise greift “row[‘Vorname’]” auf den Wert in der Spalte “Vorname” zu. Die Spaltennamen stehen in der ersten Zeile der Mitgliederliste.