COM.lounge GmbH

Wer schon immer mal wissen wollte, wo genau sich denn welche Baustellen in Aachen befinden, der konnte bislang nur die lange Liste der Stadt Aachen durchforsten. Doch viel besser wäre es doch sicher, das mal auf einer Karte anzuschauen.

Der Import der Baustellen

Das geht jetzt auch, denn wir haben uns die Liste mal genommen und mit einer Kartenanwendung versehen, die unter baustellen.offenes-aachen.de zu finden ist. Grundlage ist die oben genannte Liste, die wir leider bislang noch per Hand abtippen müssen. Das soll sich zwar irgendwann einmal ändern, wenn die neue Datenbank-Anwendung für diese Baustellen eingeführt wird, die wohl auch einen Export haben soll. Da uns das aber irgendwie zu lange dauert, haben wir das einfach schonmal selbst umgesetzt.

Die Anwendung selbst bietet im Moment nur die Basisfunktionen, man kann aber zumindest zwischen Baustellen unterscheiden, die nur auf Gehwegen stattfinden (wie Glasfaser-Ausbau) oder aber auch auf der Fahrbahn. In Kürze wird es zudem noch einen Export der Daten geben und wir arbeiten an einem Editor, um die Baustellen noch genauer einzeichnen zu können (soweit dies aus der Baustellen-Liste ersichtlich ist). Und auch eine mobile Version ist in Arbeit (vielleicht machen wir auch eine App draus).

Nicht alle Baustellen sind im Moment übrigens richtig platziert. Dies werden wir mit dem Editor dann beheben. Die Automatisierung hat bei den vorhandenen Daten leider ihre Grenzen.

Wer den Source-Code einsehen will, der kann auch dies tun, indem er einfach diesem Link folgt. Dort ist auch eine CSV-Datei der aktuellen Daten mit Stand 22.4.2013 zu finden.

Und mit diesem Blogpost ist dann auch unser neues Blog eröffnet, dass als Fokus hoffentlich auch viel Technik haben wird 🙂 (und alle weiteren Einstellung, Plugins usw. kommen dann nach der re:publica dran).

Website: baustellen.offenes-aachen.de

 

Update: Inzwischen hat die Stadt Aachen eine offizielle Schnittstelle implementiert und wir haben die Anwendung aktualisiert, so dass wir diese Schnittstelle nutzen. Kein Abtippen mehr und damit eine bessere Datenqualität sind die Folge. Außerdem ein gutes Beispiel, was man machen kann, wenn öffentliche Institutionen Ihre Daten offenlegen.

 

 

 

In meinem ersten Tutorial auf diesem Blog will ich darstellen, wie man Gemeindegrenzen auf einer Auf Open Street Map basierenden Karte darstellen kann. Die Gemeindegrenzen (in diesem Fall NRW) selbst nehme ich dabei nicht direkt von OSM, sondern aus einem Shapefile, das ich in diesem Fall von der Seite zur Landtagswahl des Innenministeriums herunterlade. Als Grundlage für die OSM-Darstellung nehme ich die JavaScript-Library leaflet.js.

Shapefile in GeoJSON überführen

Die Hauptaufgabe ist nun, das Shapefile mit den Gemeindegrenzen in das GeoJSON-Format zu überführen, denn dies ist das Format, das leaflet erwartet. Lädt man die Geometrie der Gemeinden (direkter Downloadlink) herunter und entpackt das ZIP-File, so erhält man folgende laut zu einem Shapefile zugehörigen Dateien:

DVG1_Gemeinden_utm.dbf
DVG1_Gemeinden_utm.prj
DVG1_Gemeinden_utm.shp
DVG1_Gemeinden_utm.shx

Wichtig ist dabei im Prinzip nur die Datei mit Endung .shp, da diese die eigentlichen Geometrien enthält.

Um diese Datei in GeoJSON umzuwandeln gibt es zum Glück ein Tool, dass sich ogr2ogr nennt und im GDAL-Paket zu finden ist. Unter OSX kann man dies mit macports wie folgt installieren:

sudo port install gdal +geos

Bevor man die Konvertierung startet, muss man zwei Dinge beachten. Zunächst einmal die Art der Projektion. So gibt es verschiedene Verfahren, die Erdkugel auf eine rechteckige Karte zu projizieren. Das Shapefile benutzt UTM (wie im Dateinamen zu erkennen),  leaflet bzw. OSM mag aber lieber EPSG:3857. Hier muss man also entweder umrechnen oder in leaflet die Projektion umstellen, was mit dem Plugin Proj4Leaflet geht. Ich werde hier aber die Daten schon vorher auf die Ziel-Projektion umrechnen.

Das zweite Problem ist die Datenmenge. Die Definition der Gemeindegrenzen ist nämlich sehr genau, was bedeutet, das die Polygone sehr viele Punkte beinhalten. Dies bedeutet aber, dass die Karte eher behäbig daherkommt. Da es bei der Darstellung aber eher auf die Flächen ankommt und man sowieso nicht bis auf den letzten Stein herunter zoomen kann, können und sollten diese Polygone vereinfacht werden.

Beide Probleme lassen sich glücklicherweise direkt mit ogr2ogr lösen und der zugehörige Aufruf sieht wie folgt aus:

ogr2ogr -f geojson -simplify 20 -t_srs EPSG:4326 -a_srs EPSG:4326 gemeinden.json DVG1_Gemeinden_utm.shp

Die einzelnen Argumente bedeuten dabei folgendes:

Eine Besonderheit von ogr2ogr ist dabei, dass zunächst die Zieldatei angegeben wird und dann erst die Quelldatei. Also aufpassen!

Man beachte auch die Projektion, denn entgegen meiner vorherigen Behauptung mit EPSG:3857 arbeitet leaflet dann wohl doch lieber mit EPSG:4326 (wenn ich das richtig verstehe ist letztere der Koordinatensatz auf einer Kugel, während 3857 die projizierte Version ist. Ob leaflet das dann automatisch umrechnet, ist mir nicht so ganz klar, mit 4326 funktioniert es aber auf jeden Fall).

Hat man nun die Datei, muss man sie nur noch anzeigen. Dazu initialisiert man zunächst leaflet (und jquery gleich mit). Laden wir zunächst die notwendigen Dateien vom CDN:

    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5/leaflet.css" />
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.jquery.com/jquery-migrate-1.1.1.min.js"></script>
    <script src="http://cdn.leafletjs.com/leaflet-0.5/leaflet.js"></script>

Dann noch ein bisschen CSS für eine Fullscreen-Map:

<style>
     html, body, #map {
         height: 100%;
     }
</style>

Die Karte selbst ist nur ein DIV:

<div id="map"></div>

Dann brauchen wir noch Code zum Initialisieren der Karte grob auf NRW (ausserdem benötigt man noch einen API-Key von cloudmade.com, wobei man zum Experimentieren aber alternativ auf die Tiles von OSM nutzen kann. Die Nutzung ist dort allerdings eingeschränkt):

    <script>
        $(document).ready(function() {
            var map = L.map('map').setView([51.463, 7.18], 10);
            L.tileLayer('http://{s}.tile.cloudmade.com/API-KEY/{z}/{x}/{y}.png', {
                attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery &copy; <a href="http://cloudmade.com">CloudMade</a>',
                    maxZoom: 18
            }).addTo(map);
    </script>

Nun müssen wir nur noch das GeoJSON-Objekt laden und anzeigen. Dies geschieht per getJSON-Aufruf:

$.getJSON("/gemeinden/gemeinden.json", function(data) {
    L.geoJson(data, {
        style: function(feature) {
            switch (feature.properties.KN) {
                default:
                    return {
                        fillColor: '#00'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,2)+"00",
                        fillOpacity: 0.5,
                        weight: 2,
                        color: '#111',
                        opacity: 0.7,
                        dashArray: '4'
                    }
            }
        }
    }).addTo(map);
});

Wichtig ist dabei hauptsächlich der Aufruf von L.geoJSON und der Angabe der Daten. Mit der style-Funktion ist man zusätzlich noch in der Lage einzelne Flächen einzufärben (hier per random-Grün), die Grenzen zu stylen usw. Mehr Informationen erhält man hier.

Ein komplettes Demo gibt es auch!

Heute habe ich dank des Ausfalls unseres Mailservers bei Strato den dort befindlichen Mailman auf unserem neuen Mailserver (kein Strato mehr) installiert. Da dabei ein paar Besonderheiten anfallen was die Kombination mit nginx betrifft, will ich das hier kurz dokumentieren, damit ich das beim nächsten Server schnell wieder parat habe. Ich gehe dabei davon aus, dass nginx schon installiert ist.

Zunächst einmal muss man mailman selbst installieren:

apt-get install mailman

thttpd

Da mailman auf cgi-bin aufbaut, nginx aber kein cgi-bin unterstützt, scheint der einfachste Weg zu sein, noch thttpd zu installieren (fastcgi geht theoretisch auch, wollte aber aus mir unbekannten Gründen kein PATH_INFO an Mailman weiterleiten):

apt-get install thttpd

Bei thttpd handelt es sich dabei um einen sehr kleinen HTTP-Server, der cgi-bin unterstützt und den wir als Proxy benutzen werden.
Dazu muss thttpd natürlich konfiguriert werden, was in der Datei /etc/thttpd/thttpd.conf passiert. Hier die wichtigsten Zeilen:

port=7999
dir=/usr/lib/cgi-bin
nochroot
user=www-data
cgipat=/**
host=127.0.0.1

Wichtig ist also, dass wir auf einem anderen Port als 80 laufen, dass wir nur auf 127.0.0.1 hören, dass wir kein chroot machen, unter www-data laufen und dass wir alle URLs als cgi-Scripts interpretieren und nicht nur die mit Prefix /cgi-bin/

Dann muss der Daemon noch ggf. in /etc/default/thttpd eingeschaltet werden und mit

/etc/init.d/thttpd start

gestartet.

nginx

Für nginx brauchen wir ggf. einen neuen virtual host, in den wir folgendes eintragen:

server {
    listen 80;
    server_name         meinedomain;
    access_log          /var/log/nginx/domain.access.log;
    error_log           /var/log/nginx/domain.net.error.log;
    location /mailman/ {
        proxy_pass http://127.0.0.1:7999/mailman/;
        proxy_set_header Host $host;
    }

    location /images/mailman {
        alias /usr/share/images/mailman;
    }

    location /pipermail {
        alias /var/lib/mailman/archives/public;
        autoindex on;
    }
}

Wir richten also einen ganz normalen reverse-Proxy ein.

Schliesslich müssen wir mailman nur noch sagen, dass er statt /cgi-bin/mailman jetzt auf /mailman/ hört. Dazu müssen wir die Datei /usr/lib/mailman/Mailman/mm_cfg.py anpassen, so dass die folgenden Zeilen darin vorkommen:

DEFAULT_URL_PATTERN = 'http://%s/mailman/'
PRIVATE_ARCHIVE_URL = '/mailman/private'
IMAGE_LOGOS         = '/images/mailman/'

Nach Neustart von nginx sollte dann das Mailman-Interface unter http://domain/mailman/admin/[meineliste] zu finden sein.

Das funktioniert natürlich nur, wenn Mailman und die Mailingliste auch richtig eingerichtet wurde. Dazu gibt es hier weiterführende Doku.

Weitere Hinweise zur Mailman-Migration

Da ich bei der Migration auch die URL von cgi-bin/mailman auf /mailman/ geändert habe, müssen die Listen noch angepasst werden. Dies geschieht in /var/lib/mailman über den Befehl

bin/withlist -l -a -r fix_url

Der geht alle Listen durch und trägt dort das Default-URL-Pattern ein.

Foto CC-BY-NC-SA von Éole Wind