Wed, Feb 9, 2022
tl;dr: Dieser Artikel beschreibt, wie man mit Map Machine, das in einem Docker Container läuft, Karten als SVG basierend auf OpenStreetMap generieren kann.
Map Machine ist ein Projekt, das die Fülle und Vielfalt der Daten von OpenStreetMap zeigen möchte. Es ist ein Map Renderer, der in Python geschrieben ist und unter MIT License auf GitHub veröffentlicht ist.
Um das das Docker Image für das Map Machine-Projekt bauen zu können, benötigen wir selbstverständlich auf unserem Rechner docker
und git
. Auf git
könnte man verzichten, wenn man sich das Repository als gepacktes Zip herunterlädt. Dann benötigt man halt die Software zum Zip entpacken.
Wenn Docker noch nicht installiert ist, so gibt es Anleitungen z.B. für Ubuntu oder Archlinux.
Zunächst erzeugen wir eine lokale Kopie. Dazu müssen wir das das Repository clonen (oder herunterladen und entpacken):
git clone https://github.com/enzet/map-machine.git
Anschließend können wir in das Verzeichnis map-machine
wechseln, um das Docker Image zu bauen:
docker build --pull -t strubbl_mapmachine .
Bei diesem Kommando ist der Punkt am Ende wichtig, denn er steht für das aktuelle Verzeichnis. Das bedeutet, dass im aktuellen Verzeichnis nach der Bauanleitung (Dockerfile
) für dieses Image gesucht wird.
Der Name für das Image strubbl_mapmachine
ist frei gewählt und kann natürlich anders lauten. In den folgenden docker
-Kommandos muss dies dann entsprechend angepasst werden.
Während das Image gebaut wird, können schon einige Vorbereitungen getroffen werden, um gleich einen sinnvollen Aufruf an Map Machine zu formulieren.
- Es muss ein Verzeichnis angelegt werden, in dem die Karten später zu finden sind. Außerdem sollte es ein Unterverzeichnis darin geben, um einen Karten-Cache anzulegen und zu nutzen. Ich möchte die Karten unter
$HOME/data/mapmachine/maps
und somit die Cache-Daten unter $HOME/data/mapmachine/maps/cache
ablegen. Durch die Verwendung der Variablen $HOME
wird automatisch das eigene Home-Verzeichnis verwendet, z.B. /home/strubbl
. Ich erstelle also die von mir gewünschten Verzeichnisse mit dem Ausführen des Befehls mkdir -p $HOME/data/mapmachine/maps/cache
.
- Der Bereich der Karte, die wir erstellen wollen, wird benötigt. Das nennt sich Bounding Box oder kurz bbox. Dafür gibt es ein kleines Tool von Klokan, damit man sich den gewünschten Kartenausschnitt aussuchen kann. Oben links in dem Tool ist Button mit einem Pfeil der auf ein Rechteck zeigt. Wenn man dieses Werkzeug auswählt, kann man ein Rechteck (die bbox) in der Karte zeichnen.
Dieses kann man auch nachträglich noch in der Größe anpassen. Die bbox sollte nicht zu groß gewählt werden, weil in diesem Beispiel hier die Daten direkt über die OpenStreetMap API abgefragt werden. Man kann auch über die Programmargumente eine XML-Datei mit den Kartendaten angeben, um keine Anfrage an die OpenStreetMap API senden zu müssen.
Wenn die bbox fertig eingezeichnet ist, kann man im unteren Teil Copy & Paste des Tools die bbox als Text kopieren. Das Format für die bbox sollte
CSV
sein. Dann erkennt man die durch Kommata getrennten zwei Koordinaten.
- Schließlich benötigen wir noch das Zoom-Level der Karte. Der Standardwert ist 18, wenn wir keinen angeben.
Wenn diese drei Informationen zusammengetragen sind und das Docker Image erfolgreich gebaut wurde, kann man einen Container basierend auf dem Image starten, der die Karte erstellt und sich dann wieder beendet.
Ein Aufruf könnte wie folgt aussehen:
docker run -v $HOME/data/mapmachine/maps:/maps strubbl_mapmachine render \
--cache=/maps/cache -z=17 -o=/maps/stralsund-hafen.svg \
-b=" 13.089452552,54.313679518,13.1049235336,54.3194871239"
Aufgeschlüsselt bedeutet jeder Teil des Kommandos folgendes:
- Mit
docker run
drückt man aus, dass man einen Container starten will.
- Nach dem
-v
kommt zunächst der Pfad auf unserem PC, wo die genierten Karten hingeschrieben werden sollen: $HOME/data/mapmachine/maps
. Dann folgt ein Doppelpunkt und der Container-interne Pfad /maps
.
- Anschließend folgt der Name des Docker Images, hier
strubbl_mapmachine
.
render
ist das erste Argument, dass an den map-machine
-Befehl gesendet wird, um mitzuteilen, dass eine Karte generiert werden soll.
- Mit
--cache
und dem folgenden Pfad /maps/cache
gibt man an, wo Daten, die über die OpenStreetMap API abgefragt werden, zwischengespeichert werden. Diese können dann wiederverwendet werden.
- Das Zoom-Level wird über
-z 17
angegeben, das hier auf Stufe 17 festgelegt wird.
- Den Dateinamen für die Karte kann man über den Parameter
-o
festlegen. Die Datei sollte unterhalb des Container-internen Verzeichnisses /maps/
liegen, sodass wir die Datei auch auf unserem lokalen Pfad verfügbar haben und sie nicht im Container gespeichert wird, worauf wir nicht zugreifen können sobald der Container beendet wurde. Der Container-interne Pfad wird durch unseren lokalen Pfad gemappt, siehe Parameter -v
.
- Die bbox wird über den
-b
-Parameter angegeben. Die Angabe der Koordinaten mit den Anführungszeichen und dem Leerzeichen in der Form ist wichtig, weil es sonst zu einem bekannten Fehler kommen kann.
Man muss in diesem Docker-Kommando nicht map-machine
mit angeben, weil es das Standardkommando beim Aufruf des Containers ist. Das ist so im Dockerfile definiert.
Mit dieser gewählten kleinen bbox und dem Zoom-Level 17 dauert die Generierung nur ein paar Sekunden (ca. 10 s auf einem i3-6100U mit SSD). Ein größeres Zoom-Level oder eine größere bbox verlängern den Prozess und die Größe der SVG-Kartendatei.
Z.B. die Generierung einer Karte mit der gleichen bbox aber Zoom-Level 19 dauert in etwa doppelt so lange, wobei dank Nutzung des Caches keine neuen Daten von der OpenStreetMap API abgefragt werden müssen.
Wenn das Docker-Kommando fertig ist, haben wir im Pfad $HOME/data/mapmachine/maps/stralsund-hafen.svg
unsere generierte Karte liegen.
Danke an Manfred für das Testen des Artikels und die Rückmeldungen. So haben wir zusammen den o.g. Bug gefunden.
Thu, Jan 13, 2022
In diesem Beitrag möchte ich kurz zusammenfassen, wie ich beim Kartieren eines Neubaugebietes für OpenStreetMap vorgegangen bin, für das es noch keine aktuellen Luftbilder gibt.
Warum? ⚓
Ausgehend von einer Diskussion mit dem OpenStreetMap-Nutzer Pferdo, die wir ursprünglich wegen eines Wanderweges gestartet hatten, kamen wir schnell auf das in der Nähe entstehende Neubaugebiet in Lancken. Die derzeit aktuellsten Luftbilder von Bing sind an dieser Stelle verpixelt. Luftbilder anderer Anbieter wie Esri, Maxar oder Mapbox sind leider in dieser Gegend zu veraltet.
Das liegt vermutlich daran, dass das Gebiet die ehemalige Flugabwehrraketenabteilung 4335 der NVA war und das immer noch als zu zensierendes Gebiet bei Bing vermerkt ist. Pferdo bot an, von dem Neubaugebiet Fotos mit Hilfe seiner Drohne anzufertigen und ich bot an, das in OpenStreetMap zu kartieren. Und da wären wir nun für den Ausgangspunkt dieses Blogeintrags.
Vorbereitung ⚓
Fotos auswählen ⚓
Die mir vorliegenden Drohnenaufnahmen zeigen einerseits das Neubaugebiet aus der Perspektive und aus der Draufsicht. Zum Kartieren wähle ich mir die Draufsichtfotos aus. Die Fotos von der Seite sind gut, um einzusortieren, wo die Fotos der Draufsicht anzuordnen sind.
PicLayer Plugin installieren ⚓
Um die Fotos in JOSM als Hintergrundebene einfügen zu können, benötigt man ein Plugin. Das heißt PicLayer und wird über die Einstellungen im Bereich Plugins installiert.
Fotos in JOSM laden und ausrichten ⚓
Anschließend gibt es im Menü Imagery einen Menüpunkt namens New picture layer from file…. In der folgenden Dateiauswahl suche ich die Fotos, die ich als Hintergrund nutzen möchte aus und füge sie als neue Ebenen hinzu.
Nun folgt der schwierigste Teil. Man muss jedes einzelne Foto skalieren und drehen, um es an den vorhandenen Daten und Luftbilder auszurichten. Das hat mich hier am meisten Zeit gekostet.
Nachdem das Foto als Ebene geladen ist, blende ich zunächst alle Foto- und Luftbilderebenen aus bis auf die eine, die ich ausrichten möchte. Nun muss man das kleine grüne Häkchen setzeni (1), um die Ebene zu aktivieren. Dann erst erhält man auf der linken Werkzeugleiste die Möglichkeiten zum Verschieben (2), Drehen (3) und Größe ändern (4).
Zum Ausrichten kann man nicht nur die OSM-Daten, sondern auch die anderen vorhandenen Luftbilder, wie z.B. die von ESRI, benutzen.
Das ganze Ausrichten mache ich noch mit zwei weiteren Bildern. Wenn schließlich alle Bilder ausgerichtet sind, kann man endlich kartieren.
Man sieht anhand der Verzerrungen an dem Rand der Fotos, dass die Bilder nicht perfekt ausgerichtet sind. Dazu müssten sie wahrscheinlich ordentlich zugeschnitten und die Verzerrungen am Rande der Bilder anpasst werden. Einfacher wäre es gewesen, wenn man statt mehrerer Fotos einzeln eine Collage der Fotos als eine Bilddatei erstellt. Dann müsste man nur diese eine Bilddatei als Hintergrundbild ausrichten und einpassen. Um das aber in kürzerer Zeit hinzubekommen als das einzelne Ausrichten der Fotos, bräuchte ich mehr Bildbearbeitungserfahrung.
Endresultat ⚓
Schließlich kann kartiert werden und das Endergebnis hochgeladen werden, © OpenStreetMap-Mitwirkende:
Sat, Nov 2, 2019
Intro ⚓
Dieses Wochenende habe ich mir mal Pixelfed angesehen - eine Art Instagram-Klon. Dieser Blogeintrag dient dazu, die recherchierten Informationen mal alle zusammenzutragen, weil die Dokumentation zu wünschen übrig lässt.
Pixelfed ist ein mit Laravel in PHP erstelltes Projekt. Neben PHP hat es noch weitere Abhängigkeiten zu einer Datenbank: MySQL, PGSQL und sqlite werden wohl unterstützt, wobei MySQL im Moment also default vorgesehen ist. Außerdem kommt noch Redis dazu.
Das klingt super, um es in Docker Container zu packen. Erste Aktivitäten bzgl. Docker sind in dem Projekt auch schon gestartet. Leider nutzt der Initiator des Projekts, Daniel, nicht Docker. Daher ist alles rund um Docker etwas stiefmütterlich gepflegt. Das führt also zu diesem Blog und ein paar Änderungen für Docker, die auch schon in das Projekt eingeflossen sind.
Installation ⚓
Wie in der Installtionsdokumentation geschrieben, lädt man sich zunächst eine Kopie des Projekts und erstellt die Produktionsumgebung:
git clone -b dev https://github.com/pixelfed/pixelfed.git pixelfed
cd pixelfed
cp .env.example .env
Die Datei .env
passt man entsprechend den eigenen Anforderungen an. Hierbei gibt es zu beachten, dass man den APP_KEY
mit exakt 32 zufälligen Zeichen befüllt.
Der eigentliche Weg wäre gewesen, dieses Feld leer zu lassen und mit dem Befehl php artisan key:generate
einen Key zu erstellen. Doch das befüllte bei mir dieses Feld mit einem base64 codierten Schlüssel, mit dem die Applikation nichts anfangen konnte. Also habe ich kurzerhand KeepassXC bemüht, mir 32 Zeichen Zufall zu geben und diese manuall eingetragen. Ich habe noch nicht herausgefunden, welchen Nebeneffekt das haben könnte.
Außerdem habe ich das mit key:generate
noch mit der Version v0.10.6 getestet. Mittlerweile habe ich auf den heutigen Stand vom dev
Branch gewechselt, wo ich nicht noch einmal ausprobiert habe, ob das Problem noch exisitiert.
Wenn die .env
stimmig ist, kann man die Container starten und die Datenbank erstellen:
docker-compose up
docker-compose exec app php artisan migrate --force
Feintuning ⚓
Administrator ⚓
Im Prinzip ist man damit fertig und man kann Pixelfed aufrufen, sich registrieren und es nutzen. Evtl. möchte man noch einen Adminnutzer bestimmen. Das geht mit docker-compose mit dem folgenden Kommando: docker-compose exec app php artisan user:admin ADMINUSER
, wobei ADMINUSER
durch den Nutzernamen ersetzt wird, der die Rolle zugeteilt bekommen soll.
App Unterstützung ⚓
Pixelfed unterstützt mobile Apps (noch nicht vollständig). Um die generelle Unterstützung für mobile Apps zu aktivieren, muss man laut Release Notes von v0.10.6 folgenden Schritte durchführen.
docker-compose exec app php artisan passport:keys
In die Datei .env
wird die Zeile OAUTH_ENABLED=true
hinzugefügt und anschließend die Änderung dieser Datei neu in den Cache geladen:
docker-compose exec app php artisan config:cache
Das hat bei mir aber nicht ausgereicht, sodass ich die Container mittels down
und up
neustarten musste. Ein restart
hat nicht gereicht:
docker-compose down
docker-compose up
Welche App unterstützt wird, habe ich weiter unten aufgeschrieben.
Orte ⚓
Die neue sog. “ComposeUI v4 BETA” für das Hochladen von Bilder unterstützt seit Release v0.10.1, dass man den Ort, wo das Foto erstellt wurde, festlegen kann. Um die Unterstützung für dieses Feature zu aktivieren muss man einmalig folgendes Kommando ausführen während die Docker Container laufen:
docker-compose exec app php artisan import:cities
Damit kann man beim Beitrag erstellen den Ort festlegen. Die Suche nach Orten beachtet die Groß- und Kleinschreibung.
Dateigröße für Uploads ⚓
Da ich einen nginx als Proxy für den Docker Container nutze, muss der nginx so konfiguriert werden, dass der Standwert iHv. 1 MB erhöht wird. Man sollte den Wert so erhöhen, dass er größer gleich dem Wert für Uploads ist, der in der Datei .env
eingestellt ist.
v0.10.7? ⚓
Da das Release v0.10.7 im Moment noch auf sich warten lässt, wurde verkündet, dass man den dev
Branch, der bereits 145 Commits neuer als v0.10.6 ist, nutzen soll.
Andere Benutzer finden ⚓
Um Nutzer anderer Pixelfed-Instanzen hinzuzufügen, muss man die komplette URL zu dem jeweiligen Profil in das Suchfenster in Pixelfed eingeben. Dann findet Pixelfed den Nutzer der anderen Instanz und man kann ihn hinzufügen.
Offene Punkte ⚓
Filter ⚓
Was im Moment noch nicht funktioniert, ist die Vorschau von einem Bild für verschiedene Filter. Diese Vorschau sieht man direkt nach dem Upload eines Bildes und sollte eigentlich das Originalbild anzeigen wie es mit verschiedenen Filtern aussieht. Diese Filterbilder können im Moment aber nicht angezeigt werden und die URL auf diese Bilder gibt vom Webserver ein 404 zurück.
PostgreSQL ⚓
Wenn man pgsql
als Datenbank wählt, kommt man momentan nicht weit, da diese noch nicht richtig unterstützt wird.
Welche App wird unterstützt? ⚓
Ich habe Fedilab und Fedilab Lite erfolglos getestet. Die Ansage ist aber, dass Fedilab Lite ab Version 2.23.0 Pixelfed untersützt. Nur doof, dass in F-Droid das Update immer noch nicht angekommen ist. Dort ist Version 2.22.2 noch die aktuellste. 😞
Mein Pixelfed Konto ⚓
Wer bis hier gelesen hat und mich auf Pixelfed hinzufügen möchte, kann mich unter folgender Adresse finden: https://pixel.strubbl.de/strubbl
Fri, Oct 11, 2019
In Alpine Linux basierten Dockerfiles kann man einen neuen Nutzer mit Standardbenutzerprivilegien wie folgt hinzufügen:
addgroup myuser && adduser -D -G myuser myuser
chown -R myuser: /home/myuser
In Ubuntu/Debian geht das wie folgt:
useradd -ms /bin/bash myuser
Schließlich kann man den Nutzer im Dockerfile mit USER
aktivieren und sein Home-Verzeichnis als WORKDIR
einstellen:
USER myuser
WORKDIR /home/myuser
Mon, May 20, 2019
Um auf NTFS Dateisysteme in Mac OS X schreiben zu können, kann man ntfs-3g installieren. Zunächst installiert man die Abhängigkeit [FUSE for macOS] 1 und anschließend direkt [ntfs-3g] 2.
brew cask install osxfuse
brew install ntfs-3g
Hierbei schlägt bei mir der brew link
Schritt fehl, sodass ich den mkntfs
-Befehl nicht im Pfad habe. Aber das ist okay für mich, weil mein USB-Stick schon mit NTFS formatiert ist.
Als nächstes darf man in Windows-Manier erstmal neustarten.
Nach dem Neustart kann endlich ein USB-Stick, der mit NTFS formatiert ist, gemountet werden:
sudo mkdir /Volumes/NTFS
sudo umount /dev/disk2s1
sudo /usr/local/Cellar/ntfs-3g/2017.3.23/bin/ntfs-3g /dev/disk2s1 /Volumes/NTFS -olocal -oallow_other
Der erste Befehl erstellt das Zielverzeichnis, wo der USB-Stick eingehangen werden soll. Danach wird der automatisch eingehangene, nur lesbare USB-Stick ausgehangen und schließlich mit dem dritten Befehl beschreibbar unter das Zielverzeichnis eingehangen. Doch dann kommen diverse Popups bzgl. der Sicherheitseinstellungen, die auf Risiken hinweisen.
Durch die klickt man sich und erlaubt ntfs-3g.
Schließlich wiederholt man den letzten Befehl und hat nun unter dem Pfad /Volumes/NTFS
den USB-Stick zum Beschreiben eingehangen.
sudo /usr/local/Cellar/ntfs-3g/2017.3.23/bin/ntfs-3g /dev/disk2s1 /Volumes/NTFS -olocal -oallow_other
Wenn man den USB-Stick automatisch eingehangen haben möchte, sobald man einen USB-Stick einsteckt, muss man in den Recovery-Modus booten und [der Anleitung] 3 folgen.