Kategorie: Open Source

Geodaten aus Open Street Map importieren

Die Open Street Map (OSM) bietet kostenlos Geodaten zu verschiedenen Themen. Die einzelnen Layer der Open Street Map lassen sich über eine Schnittstelle abrufen und weiterverwenden. Typische Anwendungsfälle sind beispielsweise:

  • Ich möchte eine Karte aller Landkreise (Polygone) Deutschlands erstellen.
  • Ich möchte eine Karte aller Autobahnen (Ways) in Europa erstellen.
  • Ich möchte eine Karte aller Spielplätze (Nodes) in München erstellen.

Bei der Verwendung von Open Street Map-Daten ist immer die Quelle zu nennen. Für den deutschen Sprachraum muss der Quellennachweis © OpenStreetMap-Mitwirkende lauten. Mehr Informationen dazu hier.

Datenanfrage mit Overpass Turbo
Overpass Turbo ist eine Webanwendung mit einem Wizard, der das Erstellen von Anfragen erleichtert. Zudem bietet Overpass Turbo vielen Exportmöglichkeiten.

Um zum Beispiel alle Autobahnen in Bayern zu bekommen, würde man im Wizard highway=motorway and type:way in bavaria eingeben. Eine Dokumentation der Wizard-Syntax findet sich hier. Der Wizard übersetzt die Anfrage in die Syntax der OSM Overpass API:

1
2
3
4
5
6
7
8
[out:json][timeout:25];
{{geocodeArea:bavaria}}->.searchArea;
(
  way["highway"="motorway"](area.searchArea);
);
out body;
>;
out skel qt;

Bei größeren Anfragen kann es sein, dass man das Timeout hochsetzen muss. Die Angabe des Timeouts erfolgt in Sekunden. Hat die Anfrage geklappt, kann man die Daten zum Beispiel im GeoJSON-Format exportieren und in QGIS weiterverarbeiten.

Overpass Turbo

Weitere Beispiele für Anfragen in Overpass Turbo:

  • Alle Landkreise Deutschlands: boundary=administrative and admin_level=6 and type:relation in germany
  • Touristenattraktionen in der Nähe des Marienplatzes: tourism=attraction around "Marienplatz, München"

Für das Auffinden der einzelnen Orte (Bavaria, Marienplatz etc.) nutzt Overpass Turbo den sehr mächtigen OSM-Geocoder Nominatim.

Datenanfrage mit Quick OSM (QGIS)
Quick OSM ist ein Plugin für das Gedodatenprogramm QGIS. Genau wie in Overpass Turbo hilft Quick OSM dabei Anfragen an die  OSM-API zu formulieren. Quick OSM hat jedoch den Vorteil, dass man schon eine  Übersicht der verfügbaren Layer hat und so Datensätze entdecken kann. Die so erstellte Anfrage kann dann noch verändert werden:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<osm-script output="xml" timeout="300"> 
  <id-query ref="3600051477" type="area" into="area"/> 
  // <id-query {{geocodeArea:Germany}} into="area"/> 
  <union>
    <query type="relation">
      <has-kv k="boundary" v="administrative"/>
      <has-kv k="admin_level" v="6"/> 
      <area-query from="area"/>
    </query>
  </union>
  <union>
    <item />
    <recurse type="down"/>
  </union>
  <print mode="body" />
</osm-script>

In diesem Fall wurde das Timeout auf 300 Sekunden erhöht und als zusätzlicher Filter <has-kv k="admin_level" v="6"/> eingefügt. Der zusätzliche Filter führt dazu, dass man nur Verwaltungsgrenzen auf Landkreisebene zurück bekommt. Ohne diesen Filter würde man sehr viele Daten zurückbekommen, da auch Bundeslandgrenzen, Regierungsbezirke usw. enthalten wären.

QGIS mit Overpass Turbo

Es bietet sich an, Anfragen an die OSM-API immer so einfach wie möglich zu halten und die Daten später in QGIS zu filtern. Komplexe Anfragen an die OSM-API dauern ewig.

Exportieren der Daten
Sowohl in Overpass Turbo als auch QGIS kann man die Daten als GeoJSON exportieren. GeoJSON-Dateien sind recht platzsparend, werden von einer Vielzahl an Anwendungen unterstützt und sind im Nachhinein noch berarbeitbar. Für die finale Anwendung empfiehlt sich das Format TopoJSON, welches noch deutlichen kleiner ist.

Anwendungsfall Verwaltungsgrenzen
OpenStreetMap bietet Daten für Verwaltungsgrenzen, Wahlkreise und Postleitzahlgebiete. Vor allem die Verwaltungsgrenzen braucht man im Alltag immer wieder. Im OpenStreetMap-Kontext sind diese Grenzen von Typ boundary=administrativ. Um die jeweils richtigen Grenzen zu bekommen, muss man sich mit dem Konzept des admin_levels, sprich der Verwaltungsebene, auseinandersetzen. Diese können von Land zu Land anders sein. Für Deutschland gibt es diese Verwaltungsebenen:

  1. Landesgrenze
  2. Bundesland
  3. Regierungsbezirk
  4. Landkreis / Kreis / kreisfreie Stadt / Stadtkreis
  5. Amtsgemeinde, Verwaltungsgemeinschaft
  6. Stadt, Gemeinde
  7. Stadtbezirk / Gemeindeteil mit Selbstverwaltung
  8. Stadtteil / Gemeindeteil ohne Selbstverwaltung

Um also an die Stadtbezirksteile Münchens zu kommen, müsste man die Verwaltungsgrenze (boundary=administrativ) auf der Verwaltungseben 10 (admin_level=0) anfragen.

Ich hoffe ihr könnt etwas mit dieser kurzen Anleitung anfangen. Wenn nicht, einfach in den Kommentaren nachfragen.

Beitrag teilen:

Plädoyer für mehr Open Source im Journalismus

GitHub Repository der New York Times

Der Journalismus hat Schritt für Schritt seinen Weg ins Internet gefunden. Interaktive Anwendungen und Datenjournalismus spielen einen immer größer werdende Rolle. Webseiten und Werkzeuge werden programmiert und zunehmend auch Geschichten.

Genutzt werden Anwendungen (Software) im Journalismus vor allem auf vier Ebenen:

  1. Datengewinnung und -auswertung
  2. Speichern, Verwalten und Bereitstellen von Daten
  3. Darstellung von Daten und Inhalten in Karten, Diagrammen, Animationen etc.
  4. Kommunikation und Organisation des journalistischen Prozess‘

Der journalistischen Prozess hängt mittlerweile viel von digitalen Werkzeugen ab. Zudem interessieren sich immer mehr Journalisten für Daten(-journalismus) und Programmieren. Daher ist es an Zeit, eine der besten Ideen der Softwareentwicklung auf den Journalismus zu übertragen: Open Source.

Der Begriff Open Source bedeutet „Offenlegung des Quellcodes“ (englisch: Source Code). Open Source gewann vor allem mit der Verbreitung des Internets an Bedeutung. Viele Webtechnologien die wir tagtäglich – auch unbewusst – nutzen, sind Open Source. Sie können von jedermann genutzt, verbessert und weitergegeben werden. Die kommerzielle Verwendung ist meistens erlaubt. Open Source hat viele Vorteile, die sich auch der Journalismus zunutze machen kann.

  • Transparenz: Das Offenlegen des Quellcodes ermöglicht es zu verstehen, wie eine Anwendung oder eine Geschichte funktioniert. Was wird mit den Daten gemacht? Wie kommt man zu einer Darstellung? Nur ein Bruchteil der Leser  kann programmieren und damit den Quellcode auch nachvollziehen. Jedoch vermittelt Open Source allen das Gefühl, dass sie theoretisch die formale Richtigkeit der Geschichte überprüfen könnten.
  • Fehlerkorrektur: Transparenz erfordert aber auch Mut. Vor allem aber erfordert sie den Mut Fehler eingestehen zu können. Entdeckt jemand einen Fehler im Quellcode, kann dieser ausgebessert werden. Das ist möglicherweise ärgerlich, aber besser wie wenn die Wahlergebnisse für alle Zeiten falsch dargestellt werden.
  • Nutzbarmachung & Weiterentwicklung: Wenn man ein Werkzeug entwickelt hat um Balken-Diagramme darzustellen, wieso sollte man es nicht für andere zur Verfügung stellen? Die Offenlegung des Quellcodes hätte den Vorteil, dass das Werkzeug weiterentwickeln werden könnte. Wenn man das Werkzeug das nächste Mal braucht, ist es vielleicht noch besser geworden und kann auch Torten-Diagramme darstellen. Vielleicht gelingt es auch jemandem etwas ganz Neues zu schaffen.
  • Partizipation: Wenn man über den offensichtlichen Nutzen hinaus denkt, kann Open Source auch mehr Partizipation seitens der Leser ermöglichen. Wenn die Struktur einer Geschichte bekannt ist, ist es auch einfacher diese weiterzudrehen. Open Source Plattformen wie GitHub sind letztendlich Kollaborations-Tools, welche es ihren Benutzer ermöglichen, über Ländergrenzen und Zeitzonen hinweg, zusammenzuarbeiten.

Als Journalisten fordern wir gerne Transparenz und Offenheit von allen Seiten ein, doch leben wir diese Werte auch selbst? Wenn wir von der Bundesregierung eine klares Bekenntnis zu offenen Daten und transparenten Haushalten fordern, wäre es nicht einfacher, wenn wir vormachen könnten wie das funktioniert? Open Source würde uns helfen diesen Prozess zu formalisieren. Natürlich soll und wird Open Source den Journalismus nicht fundamental umkrempeln und auch nicht die großen Aufgaben des  21. Jahrhundert lösen (Stichwort: Monetarisierung journalistischer Inhalte im Internet). Open Source soll kein Dogma sein, sondern eher eine Kultur der Offenheit und des Teiles. Open Source Software ist auch nicht automatisch gut und fehlerfrei, was uns der Heartbleed-Bug nahe geführt hat.

Natürlich ist ein gewichtiger Grund gegen Open Source der ökonomische Wettbewerb zwischen den Medien. Wieso sollte ein andere Nachrichtenseite mein Werkzeug nutzen können, in das ich viel Zeit und Geld investiert habe? Meines Erachtens sollte der Wettbewerb zwischen den Redaktionen auf Basis von gut recherchierten und originellen Geschichten ausgetragen werden und nicht auf Grundlage von Werkzeugen. Der Aufwand für die Entwicklung von Werkzeugen wird geteilt und jeder kann von der Arbeit der Anderen profitieren.

Allgemein glaube ich, dass der grundsätzliche Wille zu Open Source da ist. Die über durch Open Source transportieren Werte sind den Werten des Journalismus sehr ähnlich. In Deutschland gibt es aber bisher nur wenige konkreten Beispielen, wie man Open Source umsetzen kann. Die wohl einfachste Lösung wäre es mit kleinen Projekten anzufangen, um sich dann zu steigern. Im angelsächsischen Raum funktioniert das schon ganz gut. Mehrere große Nachrichtenorganisationen sind schon bei GitHub vertreten, einer sozialen Plattform, auf der viele bekannte Open Source-Programme entwickelt werden.

Open Source hat die Softwareentwicklung revolutioniert. Den Journalismus wird Open Source nicht revolutionieren, aber besser machen. Es wird nur Zeit endlich damit anzufangen!

Unvollständige Liste der Nachrichtenorganisationen auf GitHub:
Zeit OnlineBerliner MorgenpostNews York TimesWashington PostProRepublicaLos Angeles TimesThe Guardian und La Nación.

Sehr lesenswert: Nikki Usher von George Washington University zu Open source and journalism: Toward new frameworks for imagining news innovation

Beitrag teilen:

Nebeneinkünfte der Bundestagsabgeordneten visualisieren

Letzthin habe ich erklärt, wie man die Nebeneinkünfte der Bundestagsabgeordneten scrapen kann. Jetzt wird es Zeit diese Daten zu filtern und zu visualisieren. Leider machen es einem die angegebenen Einkommensstufen nicht gerade leicht eine eindeutige Geschichte zu finden und zu erzählen. Dazu aber später mehr.

Mein Tool der Wahl zu ersten Datenauswertung ist entweder Excel, OpenOffice oder LibreOffice. Auf der Suche nach einer Geschichte kann man schnell Daten filtern, sortieren oder visualisieren.

Eine erste Auswertung kann man über die Anzahl der Nebenkommen machen. In diesem Fall um die durchschnittliche Zahl der Nebeneinkommen pro Abgeordneten(-sitz) herauszufinden. Man sieht deutlich, welche Fraktion die meisten Nebeneinkommen hat.

nebeneinkuenfte-fraktionen
Durchschnittliche Anzahl der Nebeneinkünfte pro Sitz 

Spannend sind hierbei auch einzelne Politiker. Dr. Peter Gauweiler (CSU) und Dr. Daniela De Ridder (SPD) mit 19, beziehungsweise 13 Nebeneinkommen scheinen schwer beschäftig zu sein. Gauweiler verdient sein Geld als Anwalt in der eigenen Kanzlei und De Ridder als Beraterin im universitären Umfeld. Insgesamt haben nur ein Fünftel der Bundestagsabgeordneten ein Nebeneinkommen angegeben.

Stufenproblem: So bald man anfängt mit der Höhe der Nebeneinkünfte zu arbeiten, stößt man schnell auf ein Problem. Da nur Einkommensstufen angegeben sind, weiß man nicht genau wie viel der einzelne Abgeordnete eigentlich verdient. Es macht als Sinn, erstmal den unteren Grenzwert des Intervals für die Berechnung heranzuziehen. Für die Stufe 4, nehmen wir als ein Einkommen von 15.001 € an Damit lässt sich schon mal grob rechnen und kann sich sicher sein, dass man niemand ein zu hohes Nebeneinkommen anhängt.

Wer es nicht mehr vor Augen hat, das sind die einzelnen Einkommensstufen:

  • Stufe 1: 1.000 bis 3.500 €
  • Stufe 2: über 3.500 € bis 7.000 €
  • Stufe 3: über 7000 € bis 15.000 €
  • Stufe 4: über 15.000 € bis 30.000 €
  • Stufe 5: über 30.000 € bis 50.000 €
  • Stufe 6: über 50.000 € bis 75.000 €
  • Stufe 7: über 75.000 € bis 100.000 €
  • Stufe 8: über 100.000 € bis 150.000 €
  • Stufe 9: über 150.000 € bis 250.000 €
  • Stufe 10: über 250.000 €

Wenn wir aber mehrere Personen miteinander vergleichen wollen, reicht der untere Grenzwert nicht mehr aus. Dummerweise hat aber die Stufe 10 keinen oberen Grenzwert. Das heißt man weiß nicht, ob die Spitzenverdiener nur 250.001 € bekommen oder, überspitzt gesagt, 250.000.000 €. In meinem Diagramm habe ich versucht die nach offenen Intervalle durch einen Verlauf am oberen Ende des Balkens deutlich zu machen.

nebeneinkuenfte-topverdiener
Spitzenverdiener im Bundestag, Nebeneinkünfte in Intervallen

Auch wenn man nicht genau weiß, was Gauweiler, Stegemann, Michelbach und Harbarth tatsächlich verdienen, man kann davon ausgehen, dass es eine ganz schöne Summe ist. Ob da wohl noch Zeit für die Erfüllung des Bundestagsmandats bleibt? Hier lohnt es sich bestimmt noch mal genauer hinzuschauen.

Auch wenn man versucht die gesamten Nebeneinkünfte der einzelnen Fraktionen zu visualisieren, stößt man auf das Obergrenzenproblem. Auch hier bleibt einem nur in der Darstellung transparent zu machen, dass bei der Union das maximale Einkommen nach Oben hin offen ist.

nebeneinkuenfte-summe
Relative Nebeneinkünfte der Fraktionen pro Sitz (links) und einmal gesamt (rechts)

Das Ergebnis ist in meinen Augen eindeutig, obwohl wir nur ungefähre Intervalle angeben können. Die CDU/CSU-Fraktion hat sowohl absolut als auch relativ die höchsten Nebeneinkünfte. Ob die Nähe zur Wirtschaft gut ist, sei dahin gestellt. Für die Zukunft wäre es schön, ein noch feineres Stufenmodell zu haben. Zu dem sollte es keine Stufe 10 geben, welche nach oben hin offen ist. Im Vergleich zum vorherigen 3-Stufen-Modell ist aber auch das jetzige 10-Stufen-Modell schon eine große Verbesserung.

Interessant auch zum Weiterlesen: https://www.abgeordnetenwatch.de/blog/nebeneinkuenfte2014

Beitrag teilen:

Nebeneinkünfte der Abgeordneten mit Ruby scrapen

Die Nebeneinkünfte der Bundestagsabgeordneten sind endlich online, obwohl es diesmal ein wenig länger gedauert hat, bis auch der letzte Abgeordnete seine Einkommenserklärung abgegeben hat. Es ist immer spannend mal zu sehen was unsere Politiker eigentlich so nebenher verdienen. Da diese Daten vom Bundestag nicht systematisch aufbereitet werden, sondern auf die 631 Profilseiten der einzelnen Abgeordneten verstreut sind, fängt man erstmal nichts damit an. Um diese Daten in eine geeigneteres Format zu bringen, habe ich ein kleine Ruby-Script (Scraper) geschrieben.

Ich verwende für meinen Scraper die Ruby-Bibliothek Nokogiri. Diese Bibliothek ermöglicht es ganz einfach bestimmte HTML-Elemente über ihre Klasse oder ID anzusprechen.

1
2
3
4
require 'rubygems'
require 'nokogiri'
require 'open-uri'
require 'json'

Zuerst brauchen wir die Liste aller Bundestagsabgeordneten und den Link zu ihrem Profil. Dafür speichern wir erst mal alle Indexseiten ab. Nur die Indexseiten für die Nachnamen mit Q und X schließen wir aus, da es diese Wahlperiode keine Abgeordneten mit den entsprechenden Nachnamen gibt.

6
7
8
9
alphabeticalList = []
(('A'..'Z').to_a-['Q','X']).each do |b|
  alphabeticalList &lt;&lt; "http://www.bundestag.de/bundestag/abgeordnete18/biografien/#{b}/"
end

Als Nächstes durchsucht das Skript die alphabetischen Indizes aller Abgeordneten nach Links zu den einzelnen Profilen. Wenn alles gut läuft, kommen wir auf  631 Abgeordneten-Profile insgesamt.

11
12
13
14
15
16
17
18
19
20
profileUrls = []
alphabeticalList.each do |url|
  doc = Nokogiri::HTML(open(url))
  urlList = doc.css('ul.standardLinkliste')
  urlList.css('li a').each do |l|
    profileUrls &lt;&lt; url+l['href']
  end
  sleep 1
  puts "Getting URLs from ..."+url[-3,2]+" ...found #{profileUrls.length}"
end

Jetzt schauen wir uns die Nebeneinkünfte der einzelnen Abgeordneten an. Ich habe mich hierfür für eine Datenstruktur nach dem Schema „Wie oft?“/“Welche Höhe?“ entschieden.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
allMembers = []
profileUrls.each do |url|
  currentDoc = Nokogiri::HTML(open(url).read)
  currentDoc.encoding = 'UTF-8'
 
  nameAndParty = currentDoc.css('div.biografie h1').inner_html
  name, party = nameAndParty.split(',').map {|w| w.strip}
 
  member = {
      :name =~ name,
      :party =~ party,
      :s1m =~ 0,
      :s2m =~ 0,
      :s3m =~ 0,
      :s4m =~ 0,
      :s5m =~ 0,
      :s6m =~ 0,
      :s7m =~ 0,
      :s8m =~ 0,
      :s9m =~ 0,
      :s10m =~ 0,
      :s1j =~ 0,
      :s2j =~ 0,
      :s3j =~ 0,
      :s4j =~ 0,
      :s5j =~ 0,
      :s6j =~ 0,
      :s7j =~ 0,
      :s8j =~ 0,
      :s9j =~ 0,
      :s10j =~ 0
    }

Das HTML-Element mit der Klasse „p.voa_tab1“ enthält die Daten zu den Nebeneinkünften. Hat ein Bundestagsabgeordneter mehrere Nebeneinkünfte, kommt diese Element mehrfach vor. Jedes Mal wenn in einem Element ein bestimmtes Muster vorkommt,  wird der Zähler für das jeweilige Einkommen um 1 erhöht.

55
56
57
  currentDeclaration = currentDoc.css('p.voa_tab1')
  currentDeclaration.each do |a|
    str = a.inner_html

Wenn ein bestimmtes Muster vorkommt, wird das in der Konsole zurückgeben. Dadurch kann überprüft werden, ob der Scraper halbwegs richtig funktioniert. Jeder Abgeordnete ist ein Objekt und wird in ein Array geschrieben, es sei denn es handelt sich um Jakob Maria Mierscheid.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    for i in 1..11
      if str.match(/\bStufe #{i}\b/) &amp;&amp; str.match(/monatlich/)
        puts str
        member[:"s#{i}m"] += 1
      end
    end
 
     for j in 1..11
      if str.match(/\bStufe #{j}\b/) &amp;&amp; str.match(/\bjährlich\b|(\s20(09|10|11|12|13|14))/)
        puts str
        member[:"s#{j}j"] += 1
      end
    end
  end
 
      puts "Name: #{member[:name].ljust(30)} Party: #{member[:party].ljust(10)}"
        unless name == "Jakob Maria Mierscheid"
      allMembers &lt;&lt; member
    end
end

Am Schluss schreiben wir alle Daten noch in eine JSON-Datei. Dieses Format ermöglicht es uns die Daten direkt in einer Webanwendung zu verwenden oder eine Tabelle daraus zu erstellen.

81
82
83
File.open("outsideIncome.json","w") do |f|
  f.write(allMembers.to_json)
end

Der Scraper hat momentan noch ein paar Schwächen, die ich aber nach und nach beseitigen werde:

  • Manchmal gibt es noch doppelte Ergebnisse, wenn die Bundestagsabgeordneten mehrere Nebeneinkünfte in einer Zeile angeben
  • Es wird noch nicht unterschieden, ob jemand ausgeschieden (z.B. Edathy) oder gestorben ist, was dazu führt, dass der Scraper zur Zeit 634 Nebenabgeordnete findet.

Aber: Wie kann man das Skript jetzt eigentlich nutzen? Ganz einfach, dazu müssen nur Ruby, Ruby Gems und Nokogiri installiert werden. Ist das geschehen, kann man das Skript mit ruby meinscraper.rb im Terminal ausgeführt werden.

Das vollständige Script findet ihr auf Github, zur weiteren Verwendung freigegeben. Eine bereinigte Tabelle mit allen Nebeneinkünften habe ich bei Google hochgeladen. Ich erhebe natürlich keinen Anspruch auf Vollständigkeit und Korrektheit. Wenn ihr Fehler finden solltet, gebt mir einfach kurz Bescheid!

Beitrag teilen: