Difference between revisions of "HBUMNMapServer ger Capter 4"

From OSGeo
Jump to navigation Jump to search
Line 50: Line 50:
  
 
<br><code>
 
<br><code>
# shp2pgsql shapefile.shp tabellenname dbname > shapefile.sql
+
# shp2pgsql shapefile.shp tabellenname dbname > shapefile.sql
# psql -f shapefile.sql
+
# psql -f shapefile.sql
 
</code><br>
 
</code><br>
  
Line 63: Line 63:
  
 
<br><code>
 
<br><code>
CREATE INDEX [idxname] ON [tablename] USING GIST
+
CREATE INDEX [idxname] ON [tablename] USING GIST
            ([geofeld] GIST_GEOMETRY_OPS);
+
              ([geofeld] GIST_GEOMETRY_OPS);
 
</code><br>
 
</code><br>
  
Line 72: Line 72:
  
 
<br><code>
 
<br><code>
VACUUM ANALYZE;
+
VACUUM ANALYZE;
 
</code><br>
 
</code><br>
  
Line 80: Line 80:
  
 
<br><code>
 
<br><code>
CREATE INDEX [idxname] ON [tablename] (oid);
+
CREATE INDEX [idxname] ON [tablename] (oid);
 
</code><br>
 
</code><br>
  
Line 88: Line 88:
  
 
<br><code>
 
<br><code>
#!/bin/sh
+
#!/bin/sh
  
S2P=/usr/local/GIS/bin/shp2pgsql
+
S2P=/usr/local/GIS/bin/shp2pgsql
PROJ=26915
+
PROJ=26915
DBNAME=spatialdata
+
DBNAME=spatialdata
  
rm -rf output.sql
+
rm -rf output.sql
  
for s in *.shp; do
+
for s in *.shp; do
  SHPFBASE=`echo <math>s | sed -e s/.shp//g`
+
  SHPFBASE=`echo <math>s | sed -e s/.shp//g`
  <math>{S2P} -s </math>{PROJ} -d <math>{SHPFBASE}.shp itasca_</math>{SHPFBASE} \
+
  <math>{S2P} -s </math>{PROJ} -d <math>{SHPFBASE}.shp itasca_</math>{SHPFBASE} \
    </math>{DBNAME} >> output.sql
+
    </math>{DBNAME} >> output.sql
  echo -e "\n" >> output.sql
+
  echo -e "\n" >> output.sql
  echo -e "CREATE INDEX idx_itasca_<math>{SHPFBASE} ON \
+
  echo -e "CREATE INDEX idx_itasca_<math>{SHPFBASE} ON \
    itasca_</math>{SHPFBASE} USING \
+
    itasca_</math>{SHPFBASE} USING \
    GIST (the_geom GIST_GEOMETRY_OPS);\n" >> output.sql
+
    GIST (the_geom GIST_GEOMETRY_OPS);\n" >> output.sql
  echo -e "CREATE INDEX oid_itasca_<math>{SHPFBASE} ON \
+
  echo -e "CREATE INDEX oid_itasca_<math>{SHPFBASE} ON \
    itasca_</math>{SHPFBASE} (oid);\n" >> output.sql
+
    itasca_</math>{SHPFBASE} (oid);\n" >> output.sql
done
+
done
 
</code><br>
 
</code><br>
  
Line 116: Line 116:
  
 
<br><code>
 
<br><code>
# psgl -d spatialdata -f output.sql
+
# psgl -d spatialdata -f output.sql
 
</code><br>
 
</code><br>
  
Line 126: Line 126:
  
 
<br><code>
 
<br><code>
LAYER
+
LAYER
  NAME "strassen"
+
  NAME "strassen"
  TYPE "LINE"
+
  TYPE "LINE"
  STATUS ON
+
  STATUS ON
  CONNECTIONTYPE POSTGIS
+
  CONNECTIONTYPE POSTGIS
  CONNECTION "user=postgisuser dbname=berlin host=192.168.27.13"
+
  CONNECTION "user=postgisuser dbname=berlin host=192.168.27.13"
  DATA "the_geom from roads"
+
  DATA "the_geom from roads"
  FILTER "length >= 20"
+
  FILTER "length >= 20"
  CLASS
+
  CLASS
    COLOR 255 0 0
+
    COLOR 255 0 0
  END
+
  END
END
+
END
 
</code><br>
 
</code><br>
  

Revision as of 02:08, 23 January 2009

Datenbankanbindungen

\index{Datenbanken}(1)

Die Verwendung von Datenbanken für die Speicherung von Vektordaten\footnote{Es gibt auch Datenbanken, die Rasterdaten in Datenbanken speichern und verarbeiten. Generell ist das jedoch etwas, was man nicht wirklich haben möchte.} birgt diverse Vorteile.

Zuerst einmal ermöglicht es eine Datenhaltung, die von der eigentlichen Applikation getrennt ist: das System, das die fertigen Karten ausliefert, kann ein anderes sein als dasjenige, das die Daten hält. Das läßt sich zwar auch beispielweise über Netzwerkdateisysteme erreichen; dann müssen aber bei einer Anfrage alle Daten übertragen werden, wohingegen eine Datenbank in der Lage ist, nur die gewünschten Ergebnisse zurückzureichen.

Das impliziert auch gleich einen zweiten Vorteil: man kann auch die Berechnungen auf ein anderes System auslagern. Wenn die Datenbank in der Lage ist, die darzustellenden Shapes für einen gegebenen Ausschnitt schnell zu finden und auszuliefern, fallen diese Berechnungen auf dem kartenproduzierenden System fort. Darüberhinaus sind Datenbanken beim Lesen ihrer Daten generell erheblich schneller als es Zugriffe auf ein Dateisystem sind, sodass auch hier ein versteckter Performancegewinn winkt.

Das überhaupt beste Einsatzgebiet für eine GIS-Datenbank sind sehr große Datensätze, aus denen kleine Ausschnitte gezeigt werden, da Datenbanken auf die Geschwindigkeit der Suche optimiert sind.

Für einen sicherheitsorientierten Personenkreis ist außerdem interessant, dass jemand, der Zugriff auf das System mit dem MapServer erlangt, nicht automatisch Zugriff auf die Daten erhält.

Ein Großteil dieser Vorteile existiert ganz offensichtlich nur dann, wenn MapServer und Datenbank tatsächlich auf verschiedenen Systemen residieren. Es hindert Sie natürlich niemand daran, beides auf dem gleichen Rechner laufen zu lassen.

PostgreSQL und PostGIS

(2) \index{Datenbank!PostgreSQL} \index{PostGIS}\index{PostgreSQL}

PostgreSQL ist eine freie SQL-Datenbank, die eine komplexe Geschichte und vor allen Dingen eine Menge Namensänderungen vorweisen kann. Insbesondere aber handelt es sich um eine schnelle, hochgradig konfigurierbare Datenbank, die dem Vergleich mit den 'Großen' des kommerziellen Geschäfts gelassen entgegen sehen kann.

PostGIS ist eine Erweiterung von PostgreSQL, deren wichtigster Beitrag wohl die Implementierung eines großen Teils der Simple Features des OGC ist. Der MapServer kann mit Unterstützung für PostGIS kompiliert werden. Das interessanteste Merkmal ist wohl, dass auf diese Weise der Datenbank die Berechnung der anzuzeigenden Punkte überlassen wird.

Die Features von PostGIS, die über die Anbindung an den MapServer hinausgehen, sollen hier nicht Gegenstand der Betrachtung sein. Für ein weiteres Studium sei auf die PostGIS-Dokumentation verwiesen.

Oft ist die Frage gestellt worden, warum ausgerechnet PostGIS benutzt wurde, und nicht etwa MySQL. Der Hauptgrund ist wohl, dass die Unterstützung für Transactions\footnote{Darunter versteht man das Zusammenfassen mehrer SQL-Anweisungen zu eben einer Transaktion, inklusive der Möglichkeit, die gesamte Transaktion später rückgängig machen zu können.} in MySQL eher, nun, dürftig ist.

Details zur Installation von PostGIS finden Sie im Anhang. Die Webseite von PostgreSQL ist http:website:postgresql (ein guter Teil der Dokumentation ist dort auf deutsch erhältlich), die Website zu PostGIS ist http:website:postgis. Ein hervorragendes deutschsprachiges Buch zu PostgreSQL ist mit~hartwig:2001:postgresql im Handel erhältlich.

Nach der Installtion von Postgresql und Postgis muss das DBMS für die Nutzeranmeldung konfiguriert werden. Dazu wird dem Benutzer postgres ein Password vergeben. Als Benutzer postgres folgendes ausführen:

psql
alter user postgres with password 'newpassword';
createdb -E UTF8 postgisdb
createlang plpgsql postgisdb
psql -f /usr/share/postgresql-8.3-postgis/lwpostgis.sql -d postgisdb
psql -f /usr/share/postgresql-8.3-postgis/spatial_ref_sys.sql -d postgisdb

\subsubsection*{Vorbereiten einer Datenbank für PostGIS}

Dieser Teil gehört zum Abschnitt über die Installation von PostGIS im Anhang.

==Shapefiles in PostGIS laden==(3)

Um Ihre Shapefiles in eine PostGIS-Datenbank zu laden, benutzen Sie das kleine Werkzeug =shp2pgsql= , das als Teil des PostGIS-Quellcodes kompiliert wird. Das Programm erzeugt aus einem Shapefile eine Textdatei, die SQL-Statements zum Erstellen einer Tabelle in der Datenbank enthält. Diese Datei muß dann nur noch mittels =psql= eingelesen werden.

Ein Beispiel:


# shp2pgsql shapefile.shp tabellenname dbname > shapefile.sql
# psql -f shapefile.sql


Für gewöhnlich werden die Shapefiles für eine Applikation in verschiedenen Tabellen in der gleichen Datenbank abgespeichert; das kann je nach Anforderung natürlich anders sein.

\subsubsection*{Erstellen von Indizes}

Sobald Sie die Daten in Ihre Datenbanken geladen haben, sollten Sie einen räumlichen Index für diese Daten erzeugen. Das Erstellen eines solchen Index ist ein einmaliger Vorgang, der einige Zeit in Anspruch nehmen kann, der den Zugriff auf die Daten im Betrieb jedoch erheblich beschleunigt.

PostGIS verwendet sogenannte GiST-Indizes, was wundersamerweise für Generalized Search Trees steht.


CREATE INDEX [idxname] ON [tablename] USING GIST
             ([geofeld] GIST_GEOMETRY_OPS);


Dieser Vorgang kann auf großen Datensätzen laut Dokumentation recht lange Zeit dauern -- ich selbst habe nie mehr als einige Sekunden warten müssen.

Danach ist es sinnvoll, ein =VACUUM= auf der Datenbank durchzuführen:


VACUUM ANALYZE;


PostgreSQL beginnt dann, Statistiken und andere Informationen über die einzelnen Tabellen zusammenzustellen, die im Zusammenhang mit dem Index benötigt werden. Damit ist die PostGIS-Datenbank voll einsatzbereit.

Laut Dokumentation ist es für die Layer, die auch für Queries zur Verfügung stehen sollen, ratsam, einen sogenannten =oid= -Index zu erstellen. In Anlehnung an den GiST-Index erfolgt das folgendermaßen:


CREATE INDEX [idxname] ON [tablename] (oid);


Beispiel: Einspielen des Itasca-Demos

Um mit PostGIS erste Schritte zu unternehmen, könnte man beispielweise die Shapefiles aus dem Itasca-Demo in PostGIS-Tabellen überführen. Das möchte man jedoch kaum für jedes Shapefile einzeln und von Hand machen; ein kleines Shell-Skript hilft hier weiter:


#!/bin/sh
S2P=/usr/local/GIS/bin/shp2pgsql
PROJ=26915
DBNAME=spatialdata
rm -rf output.sql
for s in *.shp; do
  SHPFBASE=`echo <math>s | sed -e s/.shp//g`
  <math>{S2P} -s </math>{PROJ} -d <math>{SHPFBASE}.shp itasca_</math>{SHPFBASE} \
    </math>{DBNAME} >> output.sql
  echo -e "\n" >> output.sql
  echo -e "CREATE INDEX idx_itasca_<math>{SHPFBASE} ON \
    itasca_</math>{SHPFBASE} USING \
    GIST (the_geom GIST_GEOMETRY_OPS);\n" >> output.sql
  echo -e "CREATE INDEX oid_itasca_<math>{SHPFBASE} ON \
    itasca_</math>{SHPFBASE} (oid);\n" >> output.sql
done


Auch in diesem Skript sind die Backslashes an den Zeilenende dafür da, einen Zeilenumbruch anzuzeigen, der nur wegen des Drucklayouts eingefügt werden mußte.

Das Skript definiert zuerst den Pfad zum Tool =shp2pgsql= , die gewünschte Projektion als EPSG-Code und den Namen der Datenbank. Danach werden alle Shapefiles im aktuellen Verzeichnis in SQL-Befehle konvertiert und zusammen mit den Befehlen zur Indexerzeugung in die Datei =output.sql= geschrieben. Als Tabellennamen werden die Dateinamen ohne die Endung =.shp= und mit dem vorgehängten Prefix =itasca_= verwendet.

Danach kann diese Datei wie beschrieben z.B. mit


# psgl -d spatialdata -f output.sql


in die Datenbank übernommen werden.

Notation in Layern

Die Notation von PostGIS-Layern unterscheidet sich nur geringfügig von 'normalen' Vektordatenlayern. Zuerst ein Beispiel:


LAYER
  NAME "strassen"
  TYPE "LINE"
  STATUS ON
  CONNECTIONTYPE POSTGIS
  CONNECTION "user=postgisuser dbname=berlin host=192.168.27.13"
  DATA "the_geom from roads"
  FILTER "length >= 20"
  CLASS
    COLOR 255 0 0
  END
END


Der =TYPE= des Layers muß, wie für jeden Vektorlayer, gesetzt sein. Anstatt jedoch nur eine Datenquelle mit =DATA= anzugeben, wird =CONNECTIONTYPE= verwendet, um anzuzeigen, dass eine externe Verbindung hergestellt werden soll; in diesem Fall zu einer PostGIS-Datenbank.

Die Parameter, die hinter =CONNECTION= aufgelistet sind, geben die nötigen Informationen zum lesenden\footnote{Es ist beim Einsatz von Datenbanken generell eine sinnvolle Idee, für öffentlich zugängliche Applikationen einen Benutzer auf der Datenbank einzurichten, der ausschließlich lesenden Zugriff auf einen rigoros eingeschränkten Bereich besitzt.} Zugriff auf die Datenbank an: Benutzername, Paßwort und natürlich die Adresse des Datenbankservers. Hier sind noch andere Parameter möglich -- konsultieren Sie die PostgrSQL-Dokumentation, falls sie Einstellungen vorgenommen haben, die von den Defaults abweichen, beispielsweise für Ports.

Der Parameter =DATA= gibt den Namen der Spalte an, die die eigentlichen Geometrie-Daten vorhält. Bei Daten, die mit =shp2pgsql= eingespielt worden sind, ist das normalerweise =the_geom= .

=FILTER= definiert einen zusätzlichen Filter für die Anfrage, der als Zusatz zu einer SQL-Anfrage aufgefaßt werden kann, die nach einem =WHERE= folgt. Um diese Option sinnvoll nutzen zu können, muß man sich zwangsweise ein wenig mit der Abfragesprache SQL auskennen.

Danach folgen wieder die einzelnen Klassen zur Definition der Darstellung. Falls Sie an dieser Stelle =EXPRESSION= s benutzen möchten, beachten Sie bitte, dass Sie hier Feldnamen explizit angeben müssen, da es kein =CLASSITEM= in einem PostGIS-Layer gibt.

PostGIS außerhalb des MapServers

PostGIS ist als Erweiterung von PostgreSQL natürlich auch ohne den MapServer nutzbar. Dabei hält sich PostGIS an die OGC-Spezifikation mit dem Namen Simple Features for SQL ~[[]], sodass Sie mit jeder zu diesem Standard konformen Software Zugriff erhalten sollten.

FIXME:vervollständigen!1!



\chapter{Maplab}\index{Maplab}(1)

TODO: vervollständigen!!1!

Mapedit

TODO: vervollständigen!!1!

Mapbrowser

TODO: vervollständigen!!1!

GMap Factory

TODO:mehr!1!


\chapter{Chameleon}\index{Chameleon}(1)


\chapter{Mapfile-Prototyping mit vingar}