<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>PostGis on Mein Blog</title>
    <link>https://blog.velocarte66.fr/tags/postgis/</link>
    <description>Recent content in PostGis on Mein Blog</description>
    <image>
      <title>Mein Blog</title>
      <url>https://blog.velocarte66.fr/images/papermod-cover.png</url>
      <link>https://blog.velocarte66.fr/images/papermod-cover.png</link>
    </image>
    <generator>Hugo</generator>
    <language>de</language>
    <lastBuildDate>Fri, 04 Oct 2013 15:16:16 +0200</lastBuildDate>
    <atom:link href="https://blog.velocarte66.fr/tags/postgis/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>OSM: Zugriff auf die Attribute des Admin_Centre beim Rendern von Verwaltungsgrenzen</title>
      <link>https://blog.velocarte66.fr/posts/osm-zugriff-auf-die-attribute-des-admin_centre-beim-rendern-von-verwaltungsgrenzen/</link>
      <pubDate>Fri, 04 Oct 2013 15:16:16 +0200</pubDate>
      <guid>https://blog.velocarte66.fr/posts/osm-zugriff-auf-die-attribute-des-admin_centre-beim-rendern-von-verwaltungsgrenzen/</guid>
      <description>&lt;div class=&#39;drupal-import&#39;&gt;
In der OpenStreetMap-Datenbank sind die Informationen über Verwaltungseinheiten (Gemeinden, Kreise, Länder) meist auf die Grenzrelation und den Knoten mit der Rolle &lt;em&gt;admin_centre&lt;/em&gt; verteilt. Will man zum Rendern der Grenze oder Fläche einer Verwaltungseinheit auf Informationen zurückgreifen, die beim Knoten gespeichert sind, z.B. das Attribut &lt;em&gt;population&lt;/em&gt; oder &lt;em&gt;name:xx&lt;/em&gt;, dann stellt man fest, dass üblichen Werkzeuge diese Informationen nicht bereit stellen. Nachfolgend werden Methoden beschrieben, wie man dieses Problem bei mit osm2pgsql erstellten Datenbanken und bei aus OSM erzeugten Shape-Dateien lösen kann.
&lt;!--break--&gt;
&lt;h1&gt;PostGis / osm2pgsql&lt;/h1&gt;
osm2pgsql überträgt zwar Attribute der äußeren Wege, also der Wege mit Rolle outer, auf das für die Relation erzeugte Polygon, für den Knoten mit der Rolle admin_centre wird nichts vergleichbares gemacht. Es wird auch kein Link vom Polygon zum Knoten erzeugt. Die im Slim-Modus von osm2pgsql erzeugte Tabelle &lt;code&gt;&amp;lt;prefix&amp;gt;_rels&lt;/code&gt; enthält zwar in der Spalte &lt;em&gt;members&lt;/em&gt; sämtliche Mitglieder der Relation und deren OSM-ID, aber leider in einer nicht direkt und effizient mit SQL auswertbaren Form. Beispiel:
&lt;code&gt;&lt;pre&gt;
psql -d osm -c  &#34;select members from planet_osm_rels\
                     where hstore(tags)-&gt;&#39;name&#39;=&#39;Corneilla-la-Rivière&#39;;&#34;
                               members
----------------------------------------------------------------------------
{w121772197,outer,w100006391,outer,w121772204,outer,n287557758,admin_centre}
&lt;/pre&gt;&lt;/code&gt;
Die Member der Relation werden also in einem Array abgelegt, zwei aufeinander folgende Array-Elemente pro Member. Mit einer kleinen Funktion kann man die Node-Id des Admin_Centre extrahieren:
&lt;pre&gt;
CREATE OR REPLACE FUNCTION admin_centre(anyarray)
   RETURNS bigint
   LANGUAGE sql
   AS $function$
      SELECT cast(substring($1[i] from 2) as bigint)
         FROM generate_series(array_lower($1,1),array_upper($1,1),2) i 
         WHERE $1[i+1]=&#39;admin_centre&#39;;$function$
&lt;/pre&gt;
Damit kann man nun die Polygone der Verwaltungsgrenzen zusammen mit den Attributen des Admin_Centre abfragen:
&lt;pre&gt;
select poly.name, point.name, point.&#34;name:ca&#34;, point.population 
   from planet_osm_rels r, 
        planet_osm_polygon poly, 
        planet_osm_point point 
   where poly.admin_level=&#39;8&#39; 
         and admin_centre(r.members) = point.osm_id 
         and r.id = -poly.osm_id ;
&lt;/pre&gt;
Je nach Anwendungsfall und Performanceanforderung kann man damit auch die benötigten Attribute in die jeweils andere Tabelle übertragen oder eine Tabelle mit der Zuordnung von Knoten zu Relationen erstellen:
&lt;pre&gt;
create table admin_rel 
   as select -id as rel_id,
             admin_centre(members) as admin_centre
        from planet_osm_rels 
        where hstore(tags)-&gt;&#39;boundary&#39;=&#39;administrative&#39; and 
              hstore(tags)-&gt;&#39;admin_level&#39;  in (&#39;8&#39;,&#39;6&#39;,&#39;4&#39;);
&lt;/pre&gt;
&lt;h1&gt;Shape-Dateien&lt;/h1&gt;
Hierfür wird die Osmium-Bibliothek, das darauf basierende Javascript-Tool &lt;code&gt;osmjs&lt;/code&gt; und QGis benutzt. Mit &lt;code&gt;osmjs&lt;/code&gt; können auf einfache Weise Shape-Dateien aus den Objekten einer OSM-Datei zu erzeugt werden. Wie bei &lt;code&gt;osm2pgsql&lt;/code&gt; werden dabei zwar Polygone aus Grenzrelationen erstellt, aber ohne Bezug zum &lt;code&gt;admin_centre&lt;/code&gt;. Es ist jedoch möglich, eine CSV-Datei zu erstellen, welche diesen Bezug enthält:
&lt;pre&gt;
/*
  Osmium Javascript Example:  shape_export.js

  run with: osmjs -2 -m -l sparsetable -j shape_export.js OSMFILE
*/

var shp_places = Osmium.Output.Shapefile.open(&#39;./places&#39;, &#39;point&#39;);
shp_places.add_field(&#39;id&#39;, &#39;string&#39;, 12);
shp_places.add_field(&#39;type&#39;, &#39;string&#39;, 32);
shp_places.add_field(&#39;name&#39;, &#39;string&#39;, 32);

var shp_boundaries = Osmium.Output.Shapefile.open(&#39;./boundaries&#39;, &#39;polygon&#39;);
shp_boundaries.add_field(&#39;id&#39;, &#39;integer&#39;, 10);
shp_boundaries.add_field(&#39;type&#39;, &#39;string&#39;, 32);
shp_boundaries.add_field(&#39;boundary&#39;, &#39;string&#39;, 255);
shp_boundaries.add_field(&#39;admin_level&#39;, &#39;string&#39;, 255);

var csv_file = Osmium.Output.CSV.open(&#34;./rels.csv&#34;);

var node_tags = {
    place: { village: &#39;villaget&#39;, city: &#39;city&#39;, town: &#39;town&#39;} //,
    //shop: { supermarket: &#39;supermarket&#39; }
}

Osmium.Callbacks.init = function() {
    print(&#34;Init&#34;);
}
Osmium.Callbacks.node = function() {
    for (var key in this.tags) {
        if (node_tags[key]) {
            var type = node_tags[key][this.tags[key]];
            if (type) {
                shp_places.add(this.geom, { id: this.id, type: type, name: this.tags.name });
            }
        }
    }
}
Osmium.Callbacks.area = function() {
    if (this.tags.boundary) {
        shp_boundaries.add(this.geom, { id: this.id, type: this.tags.boundary, admin_level: this.tags.admin_level});
    }
}
Osmium.Callbacks.relation = function() {
   for (var key in this.members) {
      for (var key2 in this.members[key]) {
         if (key2==&#39;role&#39; &amp;&amp; this.members[key].role==&#39;admin_centre&#39;){
            csv_file.print(this.id*2+1, this.members[key].ref, 
                           this.members[key].role, this.members[key].type);
         }
      }
   }
}
Osmium.Callbacks.end = function() {
    shp_places.close();
    shp_boundaries.close();
    csv_file.close();
    print(&#34;Done&#34;);
}
&lt;/pre&gt;
Das Skript erstellt eine Shape-Datei mit den Grenzpolygonen, eine Shape-Datei mit den Place-Knoten und eine CSV-Datei, welche die Ids der Grenzpolygone und der zugehörigen Place-Knoten enthält. Dabei wird berücksichtigt, dass &lt;code&gt;osmjs&lt;/code&gt;  den Polygonen eine Pseudo-ID mit dem Wert &lt;code&gt;[2 * OSM-ID der Relation + 1&lt;/code&gt; zuweist.

Diese drei Dateien lädt man als Layer in QGis. Dann verknüpft man den CSV-Daten-Layer über die Knoten-ID mit dem Knoten-Layer und anschliessend den Polygon-Layer über die Pseudo-ID mit dem Knoten-Layer. Will man die Daten mit Tilemill / Mapnik verenden, kann man die Polygon-Layer als Shape-Datei speichern.


&lt;/div&gt;</description>
    </item>
    <item>
      <title>PostGIS: Daten für den Renderingprozess vorbereiten</title>
      <link>https://blog.velocarte66.fr/posts/postgis-daten-fur-den-renderingprozess-vorbereiten/</link>
      <pubDate>Wed, 30 Jan 2013 22:10:31 +0100</pubDate>
      <guid>https://blog.velocarte66.fr/posts/postgis-daten-fur-den-renderingprozess-vorbereiten/</guid>
      <description>&lt;div class=&#39;drupal-import&#39;&gt;
Die nachfolgende Anleitung gilt für Debian Wheezy (Stand 01/2013)
&lt;h3&gt;Anlegen der PostGIS-Datenbank&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Installation der PostgreSQL-Pakete: 
&lt;pre&gt;&lt;code&gt;aptitude install postgresql-9.1 postgresql-9.1-postgis postgresql-contrib-9.1 postgis&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Installation des Pakets &lt;code&gt;postgis&lt;/code&gt;. Wheezy enthält PostGIS 1.5. Wenn, wie in meinem Fall, Funktionen benötigt werden, die erst ab PostGIS 2.0 verfügbar sind, kann diese Version problemlos aus den Quellen installiert werden.&lt;/li&gt;
&lt;li&gt;Anlegen eines Users und einer Datenbank. Als Superuser:
&lt;pre&gt;&lt;code&gt;su - postgres
createuser &amp;lt;username&amp;gt;
Soll die neue Rolle ein Superuser sein? (j/n) j
#psql --command &#34;ALTER USER &amp;lt;username&amp;gt; WITH SUPERUSER&#34;;
psql --command &#34;ALTER USER &amp;lt;username&amp;gt; WITH ENCRYPTED PASSWORD &#39;osm&#39;&#34;;
&lt;/code&gt;&lt;/pre&gt;
Als User &lt;code&gt;&amp;lt;username&amp;gt;&lt;/code&gt;:
&lt;pre&gt;&lt;code&gt;createdb osm
psql -d osm --command &#34;CREATE EXTENSION hstore;&#34;
#createlang plpgsql osm
psql -d osm -f /usr/share/postgresql/9.1/contrib/postgis-1.5/postgis.sql
psql -d osm -f /usr/share/postgresql/9.1/contrib/postgis-1.5/spatial_ref_sys.sql 
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Importieren der OpenStreetMap-Daten mit osm2pgsql&lt;/h3&gt;
Mit &lt;a href=&#34;https://wiki.openstreetmap.org/wiki/Osm2pgsql&#34; target=&#34;_blank&#34;&gt;Osm2pgsql&lt;/a&gt; können OpenStreetMap-Daten in eine PostGIS-Datenbank importiert werden. Im Wesentlichen werden dabei die OSM-Objekte (Ways, Nodes, Relations), ihre Attribute (Tags) und Geometrie in Datenbanktabellen übernommen. Nodes werden nach &lt;code&gt;planet_osm_nodes&lt;/code&gt;, Ways nach &lt;code&gt;planet_osm_line&lt;/code&gt; und geschlossene Ways nach &lt;code&gt;planet_osm_polygon&lt;/code&gt; importiert. Welche Attribute übernommen werden sollen, wird in einer Konfigurationsdatei (Import Style) festgelegt.

Relationen vom Typ Multipolygon, Boundary und Route werden nach &lt;code&gt;planet_osm_rels&lt;/code&gt; importiert. In diese Tabelle werden nur die Attribute der Relation und Verweise auf ihre Members eingetragen. Über die Konfigurationsdatei kann festgelegt werden, dass für Relationen mit bestimmten Attributen auch die Geometrie nach &lt;code&gt;planet_osm_polygon&lt;/code&gt; bzw. &lt;code&gt;planet_osm_line&lt;/code&gt; importiert werden.

Daten importieren:
&lt;pre&gt;&lt;code&gt;osm2pgsql -c -m -s -d osm -U &amp;lt;username&amp;gt; -W -H localhost --bbox &amp;lt;bbox&amp;gt; &amp;lt;osmdatei&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;code&gt;&amp;lt;osmdatei&amp;gt;&lt;/code&gt; ist die Datei OSM-Format (.osm, .osm.bz2 ou .pbf), welche die zu importierende Daten enthält. 
&lt;h3&gt;Nachbearbeiten der importierten Daten&lt;/h3&gt;
Die mit &lt;code&gt;osm2pgsql&lt;/code&gt; und dem Default-Importstyle erzeugte Datenbank enthält alle Daten, die man für das Rendern einer Karte im OSM-Mapnik-Standard benötigt. Für einen Karte in einem davon wesentlich abweichenden Stil kann es sinnvoll bzw. notwendig sein, die importierten Daten mit SQL nachzubearbeiten. Ein einfaches Anwendungsbeispiel ist das Ersetzen der Werte &#34;yes&#34;, &#34;true&#34;, &#34;1&#34; durch &#34;yes&#34;, um Abfragen in Mapnik oder Tilemill zu vereinfachen:
&lt;pre&gt;&lt;code&gt;UPDATE planet_osm_line 
    SET  tunnel = (CASE WHEN tunnel IN (&#39;yes&#39;,&#39;true&#39;,&#39;1&#39;) 
                        THEN &#39;yes&#39;::text 
                        ELSE tunnel::TEXT 
                        END);&lt;/code&gt;&lt;/pre&gt;
Dies kann natürlich auch in der Datenbankabfrage in Mapnik/Tilemill gemacht werden. Erledigt man das bereits im Vorfeld, dann werden die Abfragen in Mapnik/Tilemill kompakter und lesbarer. Komplexere Anwendungsfälle werden in einem separaten Beitrag behandelt.




&lt;/div&gt;</description>
    </item>
    <item>
      <title>Rendern und Veröffentlichen einer OSM-Karte - Auswahl der Werkzeuge</title>
      <link>https://blog.velocarte66.fr/posts/rendern-und-veroffentlichen-einer-osm-karte-auswahl-der-werkzeuge/</link>
      <pubDate>Wed, 30 Jan 2013 16:45:33 +0100</pubDate>
      <guid>https://blog.velocarte66.fr/posts/rendern-und-veroffentlichen-einer-osm-karte-auswahl-der-werkzeuge/</guid>
      <description>&lt;div class=&#39;drupal-import&#39;&gt;
In diesem und den folgenden Beiträgen beschreibe ich meine Erfahrungen mit dem Rendern und Veröffentlichen einer Karte auf der Basis der OpenStreetMap-Daten.
&lt;h3 class=&#34;title&#34;&gt;Anforderungen und Randbedingungen&lt;/h3&gt;
Ausgangspunkt waren folgende Randbedingungen: 
&lt;ul&gt;&lt;li&gt;Die Karte soll ein Gebiet von mindestens 80 km2 abdecken, mit den Zoomleveln von 12 bis 18&lt;/li&gt;
&lt;li&gt;Die Karte soll auf einer Webseite veröffentlicht werden. Der Kostenrahmen liegt bei &lt; 5 Euro pro Monat.&lt;/li&gt;
&lt;li&gt;Arbeitsumgebung ist Linux (Debian Wheezy)&lt;/li&gt; 
&lt;li&gt;Freie Gestaltung des Kartendesigns, insbesondere soll es möglich sein, parallel versetzte Linien zu rendern, z.B. für straßenbegleitende Radwege und -spuren. &lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class=&#34;title&#34;&gt;Auswahl der Tools&lt;/h3&gt;
Für das &lt;strong&gt;Rendern&lt;/strong&gt; der Karte standen Maperitive und Mapnik zur Auswahl. Da Mapnik grundsätzlich den Einsatz einer PostGis-Datenbank erfordert und mir dies zu aufwändig erschien und zudem der erste Versuch einer PostGis-Installation scheiterte, habe ich zunächst Maperitive eingesetzt, weil es direkt mit den OSM-Daten im OSM-XML-Format arbeitet. 

&lt;strong&gt;Maperitive&lt;/strong&gt; ist eine .Net-Anwendung, lässt sich aber unter Linux mit Mono installieren und betreiben. Die Performance ist weniger gut als unter Windows aber auf meinem Phenom II X2 sind die Reaktionszeiten beim interaktiven Arbeiten im akzeptablen Bereich. Unschön ist allerdings, dass Schriften unter Linux auf Grund einer Einschränkung von Mono nicht immer sauber gerendert werden.  

Der große Vorteil von Maperitive ist die integrierte Entwicklungsumgebung, mit der Änderungen in den Stil-Dateien ohne große Verzögerung in die gerenderte Karte übernommen werden. Mit den zahlreichen verfügbaren Beispiel-Stilen kann auf diese Weise in kurzer Zeit eine individuelle Karte erzeugt werden. Ebenfalls von Vorteil sind die vielen grafischen Gestaltungsmöglichkeiten, z.B. zum Erzeugen von Mustern und Symbolen. Trotzdem war ich mit dem Endergebnis nicht zufrieden, das Kartenbild machte irgendwie einen unprofessionellen Eindruck. Das soll nicht als Kritik an Maperitive verstanden werden, möglicherweise habe ich zu früh auf andere Tools umgeschwenkt. 

Vor dem Umstieg auf Mapnik musste zunächst &lt;strong&gt;PostgreSQL&lt;/strong&gt; und &lt;strong&gt;PostGis&lt;/strong&gt; installiert werden. Das geht recht einfach, da hierfür  Debian-Pakete existieren. Wheezy enthält PostGIS 1.5., wegen eines Versuchs mit der Funktion ST_UnaryUnion habe ich nachträglich PostGIS 2.0 aus den Quellen installiert. Obwohl diese Funktion letzendlich nicht verwendet wird, bin ich bei 2.0 geblieben. 

Schwieriger war der Import der OSM-Daten in die PostGIS-Datenbank. Das lag hauptsächlich daran, dass ich das Tool &lt;strong&gt;osm2pgsql&lt;/strong&gt; erst nach ein paar Fehlversuchen mit anderen Tools gefunden habe. Beim anschließenden Test der damit erzeugten Datenbank mit &lt;strong&gt;QGis&lt;/strong&gt; habe ich festgestellt, dass sich dieses mit der neuen Symbologie hervorragend zum Rendern einsetzen lässt. Leider unterstützen die Tools zum Erzeugen von TMS-Kacheln nicht die neue Symbologie, so dass diese Spur nicht weiter verfolgt wurde, aber langfristig könnte dies eine komfortable Lösung sein.

&lt;strong&gt;Mapnik&lt;/strong&gt; ist in Debian Wheezy in der Version als Paket in der Version 2.0 verfügbar und funktioniert ohne Probleme. Da ich zum Rendern parallel versetzter Linien den LineSymbolizer-Parameter offset benötige, der erst in Mapnik 2.1 verfügbar ist, habe ich die Version 2.1. aus den Quellen installiert. Das Arbeiten mit dem XML-Format der Mapnik-Stildateien ist recht mühsam, da es keinerlei Möglichkeit von Verschachtelung oder Vererbung gibt. Das bläht die Datei enorm auf, sie wird unübersichtlich und fehleranfällig. Ich habe mich nach Alternativen umgeschaut und bin zunächst auf &lt;strong&gt;Cascadenik&lt;/strong&gt; gestoßen, das mit Stylesheets in CSS-Syntax arbeitet. Obwohl die Arbeit mit Cascadenik sehr positiv verlief, bin ich nach kurzer Zeit auf Tilemill umgestiegen, welches mit einer ähnlichen Stil-Syntax arbeitet. 

Für die Veröffentlichung habe ich mich für &lt;strong&gt;OpenLayers&lt;/strong&gt; entschieden. Es hätte aber genau so gut Leaflet sein können. 

Somit ergibt sich die folgende Tool Chain:
&lt;ul&gt;
&lt;li&gt;Importieren der OSM-Daten nach PostGIS mit osm2pgsql&lt;/i&gt;
&lt;li&gt;Nachbearbeiten der PostGIS-Daten &lt;/strong&gt;&lt;/i&gt;
&lt;li&gt;Rendern der Karte mit Tilemill&lt;/i&gt;
&lt;li&gt;Anzeige der Karte mit OpenLayers&lt;/i&gt;






&lt;/div&gt;</description>
    </item>
  </channel>
</rss>
