HBUMNMapServer ger Capter 3

From OSGeo
Jump to navigation Jump to search

OGC-Konformität

(1)\index{OGC}

Das OpenGIS Consortium, kurz OGC, ist ein internationaler Zusammenschluß von '258 Unternehmen, Regierungsorganisationen und Universitäten' (Eigendarstellung auf der Website, die Zahl ändert sich beinahe wöchentlich). Ziel des OGC ist es, gemeinsame Standards (Protokolle, Formate etc.) für Austausch, Verarbeitung und Speicherung von Geo-Daten zu erarbeiten.

Die Standards, die uns bei der Erstellung von OGC-konformen MapServern im Internet interessieren können, sind vielfältig. Für den MapServer sind die folgenden Standards relevant bzw. implementiert:


  • OGC Web Mapping Server Specification, für den Transfer von Rasterkarten und eventuelle Anfragen auf diese Daten, und
  • OGC Web Feature Server Specification, was das gleiche für Vektordaten und eventuelle Anfragen auf diese Daten ist.

Darüber hinaus werfen wir auch noch einen raschen Blick auf die


  • Map Context Specification,

die bisher allerdings nur sporadisch umgesetzt ist.

Die Website des OGC ist unter~http:website:ogc zu erreichen.

Warum macht man das?

Eine berechtigte Frage ist natürlich, warum man diese Funktionalität überhaupt haben wollen könnte. Die Antworten sind vielfältig. Hier einige Beispiele:

\subsubsection*{Kein Zugang zu den Originaldaten}

Die wenigsten Besitzer von Geodaten rücken diese umsonst, oder überhaupt heraus. Manche sind allerdings durchaus gewillt, Karten auszuliefern; ihre Originaldaten kommen dabei nicht an die Öffentlichkeit. Durch die Bereitstellung von Karten nach den Kriterien des WMS sind darüberhinaus nicht nur Sie, sondern auch andere in der Lage, Karten aus der 'schwierigen Quelle' zu beziehen. Die Existenz eines Standards kann also schon zur Verbreitung von Kartenmaterial beitragen.

\subsubsection*{Lastenverteilung}

Ähnlich wie bei Datenbankanbindungen -- siehe auch Kapitel~\ref{text:database} -- kann beispielweise ein WMS-konformes zur Verteilung von Rechenlast beitragen, indem einzelne Layer der Karte einfach auf verschiedene Rechner verteilt werden.

\subsubsection*{Herstellerunabhängigkeit}

Durch ein standardisiertes Kommunikationsprotokoll sind Sie in der Lage, sich den Hersteller Ihrer Software auszusuchen. Umgekehrt bedeutet das auch, dass Sie nicht auf die Software eines bestimmten Herstellers angewiesen sind, wenn beispielsweise auf einen WMS-konformen Server zugegriffen werden soll. Die Wahl der Software kann also eher an anderen Kriterien (z.B. dem Preis) ausgerichtet werden.

Auf der Website des OGC finden Sie eine Liste von Herstellern und Produkten~http:website:ogcnetwork:impl und eine Beschreibung, welche Standards in welcher Version von ihnen unterstützt werden.

\subsection*{Existenz von Evaluationskriterien}

Häufig steht man vor der Frage, welches Produkt man für einen besonderen Zweck einsetzen soll. Das richtige Vorgehen ist natürlich, sich klarzumachen, welche Eigenschaften und Möglichkeiten die Software bieten soll, und anhand einer daraus hervorgehenden Liste kann man dann verschiedene Produkte evaluieren.

Solch ein Evaluationsvorgang kann zeitlich und finanziell sehr aufwändig sein. Weithin anerkannte Standards helfen dabei, Entscheidungen anhand fertig vorliegender Kriterienkataloge zu treffen.

Web Mapping Server (WMS)

Von besonderem Interesse ist die OpenGIS Web Map Server Interfaces Implementation Specification , im folgenden kurz WMS-Standard genannt. Diese Spezifikation liegt inzwischen in der Version 1.1.1~pdf:spec:ogc111 vor. MapServer unterstützt aber auch die zurückliegenden Standards 1.0.0~pdf:spec:ogc100 und 1.1.0~pdf:spec:ogc110.

Sinn der WMS-Spezifikation ist es, ein offenes, definiertes Interface sowohl für Clients als auch für Server zur Verfügung zu stellen, die Karten und Daten über diese Karten miteinander austauschen wollen. Zur Kommunikation zwischen den Servern und Clients wird das HTTP-Protokoll verwendet. Über das Protokoll werden Daten im XML-Format übertragen\footnote{Für Exceptions sind auch andere Formate möglich.}. Parsen und weiterverarbeiten läßt sich XML in fast jeder bekannten Programmiersprache. Auf diese Weise ist man nicht an Webapplikationen gebunden, wenn man ein Programm entwickeln möchte, das mit einem WMS-Mapserver 'redet'. Die dazugehörige DTD\footnote{Die sogenannten document type definitions dienen der Validierung von Dokumenten. Sie können ein DTD also benutzen, um zu testen, um ein Dokument einem bestimmten Rahmen an Vorgaben genügt.} ist vom OGC zu beziehen und in der Spezifikation beschrieben. Gedruckt lernen Sie mehr über XML durch die Lektüre von~ray:2001:xml, online finden Sie die Spezifikationen unter~http:homepage:xml.

\subsubsection*{Hinweis}

Eine zentrale Rolle bei der Verwendung von WMS spielt die Umprojizierung von Daten. Da bei WMS Rasterdaten zum Einsatz kommen\footnote{Die Datenquelle für den Server kann natürlich ein Vektorformat haben. Produziert werden aber ausschließlich Rasterdaten, wie wir es bisher immer beim MapServer gesehen haben.}, und MapServer Rasterdaten ausschließlich unter Zuhilfenahme der Bibliothek GDAL umprojizieren kann, sollten Sie MapServer mit der Unterstützung für GDAL kompiliert haben.

==Servermodi==(2)

Die genannten Spezifikation in ihrer letzten Version verlangt: es müssen zwei Arten von Anfragen implementiert sein, zwei weitere sind optional und können implementiert sein. Die beiden folgenden Anfragen (weiterhin auch Requests genannt) müssen vorhanden sein:


  • =getCapabilities= : Diese Anfrage muss ein XML-Dokument zurückliefern, das die Fähigkeiten des Mapservers beschreibt.
  • =getMap= : Auf diese Anfrage wird eine Karte als Rasterbild zurückgeliefert.

Entsprechend der Anforderung sind diese beiden Anfragen auch im MapServer implementiert.

Die beiden Fähigkeiten, die implementiert sein können , sind:


  • =getFeatureInfo= : auf diese Anfrage liefert der Mapserver Informationen über einen bestimmten Punkt in einer Karte zurück. Diese Informationen können entweder in einer reinen Textdarstellung oder in GML (einem XML-Format) zurückgegeben werden.
  • =describeLayer= liefert ein XML-Dokument mit detaillierten Informationen über einen Layer zurück. Dieser Modus wäre für einen SLD\footnote{Styled Layer Descriptor}-konformen MapServer interessant, aber dieser Standard hat bisher noch keine Umsetzung im MapServer erfahren.

Das einzige Feature, das im MapServer zurzeit nicht implementiert ist, ist demnach =describeLayer= . Es gibt noch einige andere Modi; mehr dazu in Abschnitt~7

==Der aufrufende URL==(3)

Der Aufruf eines WMS-Servers erfolgt ganz ähnlich dem Aufruf des UMN MapServers, nämlich über einen URL mit den gewünschten Parametern. Die Benennung der Parameter, ihr Verhalten und ihre Wirkung unterscheiden sich jedoch mehr oder weniger stark von dem, was Sie bisher von ihrem MapServer gewohnt sind.

Schauen Sie sich einmal einen Aufruf für eine Karte als Beispiel an. Um die Generierung solcher URLs müssen Sie sich im Detail nicht kümmern; wenn Sie einen Server betreiben, dann sowieso nicht, weil der Aufrufende die URLs kennen muß, und nicht Sie; und wenn Sie MapServer als Client betreiben, dann müssen Sie zwar einige Angaben im Mapfile zwingend machen, aber alle dynamischen Parameter werden von MapServer aufgefüllt.

Nun aber ein Beispiel für einen WMS-konformen URL des MapServers:


http://www.example.com/cgi-bin/mapserv

    ? map=/usr/local/mapserv/mapfile.map
    & VERSION=1.1.0
    & REQUEST=getMap
    & FORMAT=image/png
    & LAYERS=gruenflaechen,fluesse,bebauung
    & SRS=EPSG:4326
    & BBOX=5.0,45.0,15.0,55.0
    & WIDTH=500
    & HEIGHT=500
    & TRANSPARENT=yes


Den ersten Parameter, das Mapfile, kennen Sie bereits. Ein Parameter =map= ist in der WMS-Spezifikation allerdings nirgends erwähnt, sodass der Aufruf streng genommen nicht standardkonform ist. Wie man sich dieses Parameters entledigen kann, erfahren Sie weiter unten auf Seite~\pageref{text:wms:mapfilename}.

Als nächstes wird mit =VERSION= angegeben, in welcher WMS-Version man die Kommunikation wünscht. Laut Spezifikation soll dabei im Hintergrund eine Aushandlung der Version stattfinden, falls eine Seite eine angegebene Version nicht kennt; Client und Server handeln sich dann gegenseitig herunter, bis sie auf eine Version treffen, die sie beide verstehen. Beachten Sie bitte, dass Sie für die Notation im Mapfile -- wenn Sie einen WMS-Layer von einem anderen Server einbinden -- die korrekte Version angeben, da MapServer diese Aushandlung nicht vornimmt.

Der Parameter =REQUEST= gibt die Art der Anfrage an. Die in MapServer implementierten Modi sind bereits weiter oben in Abschnitt~2 genannt worden. Beachten Sie, dass die Schreibweise von =getMap= bezüglich der Klein- und Großbuchstaben irrelevant sein sollte. Das gleiche gilt auch für die Namen der Parameter wie =VERSION= , =REQUEST= und so weiter. Die Großschreibung erfolgt hier nur wegen der besseren Lesbarkeit.

Die Angabe =FORMAT= wird als sogenannter MIME type gemacht, eine standardisierte Notation für die Art von über das Netz geschickten Daten. Bildformat folgen prinzipiell dem Muster =image/= plus angehängtem Namen des Bildformats, also zum Beispiel =image/jpeg= für JPEG-Bilder. Mehr über MIME-Typen inklusive Links zu den diversen zuständigen RFCs finden Sie auf~http:homepage:mime.

Es folgen die Layer, die angezeigt werden sollen. Anders als beim 'klassischen' MapServer, wo die Layernamen einzeln jeweils mit =layer== notiert werden, wird bei WMS-konformen Servern eine Liste der gewünschten Layer benötigt, wobei die einzelnen Layer durch Kommata voneinander getrennt werden. Dabei ist die Reihenfolge wichtig: der zuerst genannte Layer wird als erste Ebene in die Karte gezeichnet, liegt also zuunterst. Die im Mapfile festgelegte Reihenfolge spielt keine Rolle mehr.

Mit =SRS= wird das spatial reference system definiert, also die gewünschte Projektion angegeben. WMS verlangt EPSG-Codes für die Notierung der Projektion, wobei das Schlüsselwort =EPSG= und die dazugehörige Zahl durch einen Doppelpunkt voneinander getrennt werden.

Ähnlich wie die anzuzeigenden Kartenebenen werden auch die gewünschten Extents durch mehrere Werte angefordert, die in einer Liste durch Kommata voneinander getrennt sind. Beim 'klassischen' MapServer heißt der Parameter noch =imgext= , und die Werte werden jeweils durch ein =+= verbunden.

=WIDTH= und =HEIGHT= geben die Größe in Pixeln vor, die die fertige Karte haben soll. Beachten Sie, dass dieser Wert -- wie schon von MapServer gewohnt -- immer Vorrang vor den benannten Extents hat. Betrachten Sie folgenden Ausschnitt aus einem URL:


 & WIDTH  = 100
 & HEIGHT = 100
 & BBOX   = 0.0, 0.0, 10.0, 15.0


Augenscheinlich soll die fertige Karte quadratisch sein, wobei die Extents allerdings deutlich höher als breit sind. Das passiert -- allerdings mit kleineren Abweichungen -- bei praktisch jedem Kartenaufruf. Letztendlich werden die Extents angepaßt, die Ausmaße des Kartenbildes werden nicht angepaßt.

Schließlich und endlich wird mit =TRANSPARENT= die Hintergrundfarbe der Karte transparent geschaltet. Das will man offensichtlich dann haben, wenn man unter dieser Kartenebene noch andere Layer anzeigen möchte.

Das Ergebnis dieses Aufrufes ist also eine 500 mal 500 Pixel große, auf EPSG-Code 4326 projizierte Karte im PNG-Format mit den angegebenen Extents und transparentem Hintergrund. Der aufrufende URL dieser Karte kann entweder so bei Ihnen im Webbrowser erscheinen, oder aber von MapServer dynamisch für die Anzeige als Rasterlayer generiert worden sein.

Als nächstes schauen wir uns an, wie aus einem bestehenden Mapfile eines gemacht werden kann, das für WMS-konformes Verhalten nach außen sorgt.

==WMS-Metadaten im Mapfile==\index{Metadaten}

Zuallererst benötigt ihr Mapfile einen Namen. Im Header muß also der Parameter =NAME= definiert sein.

Einen 'minimalen' WMS-Server erhalten Sie zum einen durch Metadaten in der =WEB= -Sektion des Mapfiles, zum anderen durch Metadaten in den einzelnen Layern. Einige davon sind zwingend erforderlich, andere optional. Wie die Notation von Metadaten im Mapfile generell erfolgt, haben Sie bereits in Abschnitt~\ref{text:mapfile:web:meta} erfahren.



WEB

 ...
 METADATA
   "wms_title" "Ein WMS-Server"
   "wms_onlineresource" \
      "http://www.example.com/cgi-bin/mapserv?map=mapfile.map&"
   "wms_srs"  "EPSG:31464 EPSG:4326"
 END

END


Der =wms_title= ist der Titel für die Karte, dieser muß angegeben werden. Der zweite Parameter gibt an, unter welchem URL der Server aufzurufen ist.

Beachten Sie dabei, das =\&= anzugeben, bzw. ein Fragezeichen, wenn Sie nach dem eigentlichen CGI-Programm keinen Parameter zu stehen haben.

=wms_srs= steht für die Projektion, in der die Karten angeboten werden können. Die Spezifikation schreibt vor, dass hier immer mindestens EPSG-Code 4326 angeboten werden muß. Mehrere Projektionen werden einfach durch Leerzeichen voneinander getrennt. Mehr zu EPSG und Projektionen im allgemeinen haben Sie schon in Abschnitt~\ref{text:map:projections} erfahren.

Sie benötigen =wms_srs= nicht, wenn Sie für die Karte einen Projektionsblock mit EPSG-Angabe definiert haben; die =WEB= -Sektion 'erbt' dann diese Projektion als Vorgabe.

Was machen Sie, wenn Ihre Daten allesamt in einer Projektion vorliegen, für die es keinen EPSG-Code gibt? Dann können Sie einen =PROJECTION= -Block definieren, der Parameter für die Projektionsbibliothek proj.4 enthält (das Beispiel stammt direkt aus der MapServer-Dokumentation):


PROJECTION

 "proj=lcc"
 "ellps=GRS80"
 "lat_0=49"
 "lon_0=-95"
 "lat_1=49"
 "lat_2=77"

END

Wenn Sie nun EPSG-Codes in =wms_srs= nach außen anbieten, werden die Daten automatisch umprojiziert.

\subsubsection*{Notwendige Metadaten in den Layern}

Des weiteren müssen nun in jedem Layer zusätzliche Angaben nach folgendem Muster gemacht werden:


LAYER

 NAME "einlayer"
 ...
 METADATA
   "wms_title" "Titel fuer den Layer"
   "wms_srs"  "EPSG:31494"
 END

END

Daneben muß auch in jedem Layer ein Name gesetzt und eine Projektion definiert sein. Als Standardvorgabe erbt jeder Layer die Projektionen aus der =WEB= -Sektion, sodass sie nicht noch einmal neu notiert werden müssen.

Sie benötigen natürlich immer noch eine Projektionsangabe im Layer in Form eines =PROJECTION= -Blocks, um zu definieren, in welcher Projektion die Datenquelle vorliegt, damit MapServer im Zweifelsfall korrekt projizieren kann. Das gilt natürlich insbesondere dann, wenn Sie mehr als nur eine Projektion anbieten wollen.

MapServer geht im übrigen davon aus, dass sie tatsächlich alle Layer im Mapfile nach außen zur Verfügung stellen wollen. Layer, die sie nicht nach außen geben wollen, haben also in diesem Mapfile nichts verloren. Es gibt bisher keinen Mechanismus, mit dem man einzelne Layer (oder alle) in einem Mapfile von der Auslieferung per WMS ausschließen kann.

\subsubsection*{Metadaten in der Web-Sektion}

Im folgenden sind alle Metadaten beschrieben, die Sie für einen WMS-konformen Server in der =WEB= -Sektion des Mapfiles notieren können. Alle Angaben sind optional, falls nicht anders angegeben.


  • =wms_abstract= Eine elaborierte Zusammenfassung dessen, was der Server soll und ist.
  • =wms_accessconstraints= Gibt Zugangsbeschränkungen für den MapServer an. Beachten Sie bitte, dass ein Eintrag hier lediglich eine Absichtserklärung ist. Ein Text wie 'Dieser Server darf nur im Intranet unserer Firma verwendet werden' ist natürlich schön und gut, aber die entsprechenden Zugriffsbeschränkungen sind selbtsverständlich nur durch die entsprechende Konfiguration der Systeme zu erreichen.
  • =wms_addresstype= Art der Adresse. Für dieses und die folgenden fünf Felder gilt, dass bei Angabe eines der Felder auch die anderen fünf mit Inhalt gefüllt werden müssen.
  • =wms_address= Die Adresse.
  • =wms_city= Adressbestandteil: Stadt
  • =wms_country= Adressbestandteil: Land
  • =wms_postcode= Adressbestandteil: Postleitzahl
  • =wms_stateorprovince= Adressbestandteil: Staat oder Provinz
  • =wms_contactelectronicmailaddress= Emailadresse einer Kontaktperson für diesen Server
  • =wms_contactoraganization= Organisation der Kontaktperson
  • =wms_contactperson= Name der Kontaktperson für diesen Server
  • =wms_contactposition= Position der Kontaktperson innerhalb ihrer Organisation
  • =wms_contactvoicetelephone= Telefonnummer der Kontaktperson
  • =wms_fees= Art und Umfang der Gebühren, die für die Nutzung dieses Servers fällig werden. Genau wie bei =wms_accessconstraints= ist dies lediglich eine Absichtserklärung; wenn Sie Gebühren für die Verwendung des Servers erheben möchten, müssen Sie die Zugriffskontrolle durch eine geeignete Systemkonfiguration und ein passendes Geschäftsmodell herbeiführen.
  • =wms_keywordlist= Eine Liste von Schlüsselworten, die auf den Server zutreffen. Dieser Parameter ist mit dem Blick darauf geschaffen worden, dass es eines Tages in einer eigens dafür geschaffenen Datenbank eine Sammlung von Capabilities-Dokumenten geben könnte, die dann die Schlüsselwortlisten durchsuchen kann. Bisher gibt es keine solche Datenbank. Es sind auch keine Standardschlüsselwörter definiert.
  • =wms_onlineresource= Der URL, mit dem der Server aufgerufen wird. Beinhaltet beim UMN MapServer meistens:
    http://www.example.com/cgi-bin/mapserv?
    und gegebenenfalls daran angehängt noch das Mapfile. Wenn ein Mapfile über =map== angehangen wird, darf nicht das abschließende =\&= vergessen werden! Dieser Parameter ist zwingend notwendig.
  • =wms_resx= Horizontale Auflösung der Karte in Pixeln.
  • =wms_resy= Vertikale Auflösung der Karte in Pixeln.
  • =wms_srs= Projektion(en), in der die Karte angeboten werden kann. Dieser Parameter mit mindestens einer Projektion ist zwingend notwendig.
  • =wms_title= Titel der Karte. Dieser Parameter ist zwingend notwendig.

\subsubsection*{Metadaten in den einzelnen Layern}

Im folgenden die Metadaten, die Sie für einen WMS-konformen MapServer in den einzelnen Layern im Mapfile definieren können. Alle Parameter sind optional, sofern nicht anders angegeben.


  • =wms_abstract= Elaborierte Zusammenfassung dessen, was dieser Layer soll und ist.
  • =wms_extent= Die Bounding Box des Layers.
  • =wms_keywordlist= Eine Liste von Schlüsselworten, die auf diesen Server zutreffen. %
  • =wms_opaque= FIXME: was ist das?
  • =wms_srs= Projektion(en), in der die Karte angeboten werden kann.
  • =wms_title= Titel des Layers. Dieser Parameter ist zwingend erforderlich.

\subsubsection*{Das Mapfile als Parameter}(4)

Der Name des Mapfiles in der URL-Zeile ist nicht Bestandteil eines OGC-konformen Aufrufs des Mapservers. Unter Sicherheitsaspekten kann es darüber hinaus eventuell nicht angebracht sein, dem Client etwas über die Verzeichnisstruktur des Server-Systems zu verraten.

Im Moment gibt es zwei verschiedene Wege, den Ort des Mapfiles vor Außenstehenden zu verbergen:


  • Verwenden eines Wrapper-Skripts : Anstatt des CGI-Binaries wird ein kleines Skript aufgerufen, das die Umgebungsvariable = MS_MAPFILE = setzt und dann seinerseits das CGI-Programm aufruft. Ganz primitiv könnte ein solches Skript für die Shell =bash= etwa wie folgt aussehen:
    #!/bin/sh MS_MAPFILE=/usr/local/there/is/my.map export MS_MAPFILE /usr/local/httpd/cgi-bin/mapserv
    Beachten Sie bitte, dass dieses Beispiel nur für Unix-Systeme funktioniert, auf denen die Shell =bash= installiert ist. Für andere Shells kann die Notation abweichen.
  • Webserver-Konfiguration : Der Webserver ist unter Umständen in der Lage, für bestimmte aufgerufene URLs spezifische Umgebungsvariablen zu setzen. Im Apache sähe ein Eintrag in der Datei httpd.conf dann beispielsweise folgendermaßen aus (wegen der Zeilenlänge für das Drucklayout umgebrochen, muß in der Konfigurationsdatei eine Zeile sein):
    SetEnvIf Request_URI "/cgi-bin/mapserv" \ MS_MAPFILE=/usr/local/there/is/my.map
    Dieser Eintrag funktioniert nur im Apache und kann für andere Webserver vollkommen anders aussehen. Konsultieren Sie Ihre Dokumentation.


\subsubsection*{getCapabilities}(5)

Nachdem man zufrieden mit seinem Setup ist, möchte man es natürlich ausprobieren. Dazu ruft man als erstes das Capabilities -Dokument ab:


http://server/cgi-bin/mapserv?VERSION=1.1.0&REQUEST=getCapabilities \

    &map=mapfile.map 


Dabei müssen Sie bei =getCapabilities= nicht auf Groß- oder Kleinbuchstaben achten. Ebensowenig bei allen anderen Parametern, die vor einem Gleichheitszeichen stehen.

Der Webserver sollte Ihnen nun eine Datei des Typs =application/vnd.ogc.wms_xml= zurückliefern. Diese Textdatei können Sie abspeichern und in einem beliebigen Texteditor öffnen. Eventuell ist Ihr Webbrowser auch von sich aus in der Lage, XML-Dateien automatisch in einem ansprechenden Layout darzustellen.

Schauen Sie sich nun den Inhalt der Datei genau an. Wo immer Sie auf Zeilen treffen, die



beinhalten, gilt es, etwas zu bereinigen. Beispielsweise erfahren Sie aus einer Warnung wie dieser:



dass Sie einen Meta-Tag für den Titel der entsprechenden Sektion vergessen haben.

Sobald Sie keine Warnungen dieser Art mehr in Ihrem Capabilities-Dokument finden, ist ihr MapServer WMS-konform und voll einsatzbereit.

\subsubsection*{getMap}

Wenn die Capabilities wie erwartet geliefert werden, ist der nächste logische Schritt natürlich, sich eine Karte von Hand abzuholen. Dafür konstruieren Sie sich in Ihrem Webbrowser einen Aufruf, der etwa so aussieht, wie das Beispiel in Abschnitt~3. Dabei machen Sie sich dann auch gleich mit der Benennung der Parameter vertraut.

Das beste was Ihnen passieren kann, ist natürlich, dass Sie gleich ihre gewünschte Karte bekommen. Dann sind Sie natürlich fertig. Sobald Sie jedoch Ihren ersten Fehler machen, müssen Sie sich mit Fehlermeldungen auseinandersetzen, den so genannten Exceptions.

==Exceptions==\index{Exceptions}\index{WMS!Exceptions}

Exceptions sind Meldungen, die von einem WMS-konformen Mapserver im Fehlerfall ausgegeben werden müssen. Das entspricht in etwa dem Expcetions-Konzept diverser Programmiersprachen wie z.B. Java. Der Sinn ist es, dem aufrufenden Client -- sei es nun eine menschliche Person, sei es eine Software -- anhand des Typs und des Inhalts der Fehlermeldung eine Entscheidung über das weitere Vorgehen treffen zu können. Eine solche Art der Fehlerbehandlung verhindert natürlich unter anderem, dass ein Programm seine Durchführung im Fehlerfall einfach beendet.

Wenn Sie bei einem WMS-konformen Aufruf einen Fehler machen, indem Sie beispielsweise einen Parameternamen wie =REQUEST= absichtlich falsch schreiben, wird Ihnen MapServer eine Datei in einem XML-Format zurückliefern:


  • =application/vnd.ogc.se_xml= Ein WMS-konformer Mapserver muß mindestens diese Art der Vermittlung von Exceptions beherrschen. Solch eine Datei kann beispielsweise folgenden Inhalt haben:
    <?xml version='1.0' encoding="ISO-8859-1" standalone="no" ?> <!DOCTYPE ServiceExceptionReport SYSTEM "http://www.digitalearth.gov/wmt/xml/exception_1_1_0.dtd"> <ServiceExceptionReport version="1.1.0"> <ServiceException> msWMSDispatch(): WMS server error. Incomplete WMS request: REQUEST parameter missing </ServiceException> </ServiceExceptionReport>

\begin{figure} \begin{center} \mmfig{0.6}{wms-exception-inimage}{Exception vom Typ application/vnd.ogc.se_inimage.} \end{center} \end{figure}

Des weiteren kann ein Mapserver Exceptions in den folgenden MIME-Typen zur Verfügung stellen:


  • =application/vnd.ogc.se_inimage= Die Exception wird als Text in das auszuliefernde Bild eingefügt.
  • =application/vnd.ogc.se_blank= Die Spezifikation geht von der Idee, dass ein leeres Bild etwas ist, dass man grundsätzlich nicht haben möchte, und somit nie bekommt. Daher kann ein 'leeres' Bild als Fehlermeldung angesehen werden. Als 'leeres' Bild ist ein Bild definiert, das ganz mit der Hintergrundfarbe der Karte ausgefüllt ist.

Im URL des Aufrufs wird die gewünschte Art der Exception mit dem Parameter =EXCEPTIONS= notiert. Wollen Sie Exceptions also im Bild notiert haben, schreiben Sie in Ihrem URL:


... & EXCEPTIONS=application/vnd.ogc.se_inimage & ...

Beachten Sie bitte, dass nur die XML-Variante implementiert sein muß. Wenn Sie von einem Server Exceptions im Bild verlangen, er aber nur XML kann, dann wird er XML liefern.

Beachten Sie außerdem, dass das Handling von Exceptions insbesondere bei Kaskaden von WMS-konformen Servern eine Rolle spielt. So kann es Ihnen passieren, dass Sie sich einen Layer von einem Server holen, der sich wiederum sein Bild von anderen entfernten Quellen heranholt, und von dort im Fehlerfall eine Exception in das Bild eingetragen bekommt. Dadurch haben Sie die Fehlermeldung dann natürlich auch im Bild zu stehen.

Hinweis

Viele Kartenanbieter tendieren dazu, ihre fertigen Karten mit Schriftzügen, Logos, Nordpfeilen, Wasserzeichen und so weiter auszustatten. Denken Sie immer daran, dass der Kunde, der Ihren Service wiederum als Datenquelle benutzt, eventuell auf die Idee kommt, die von Ihnen bezogene Karte umzuprojizieren! Das kann dann zu interessanten Effekten führen, wenn dann Dritte den Schriftzug mit der URL Ihrer Firmenwebsite quer über die ganze Karte gekrakelt bekommen. Entwickeln Sie im Vorhinein zusammen mit den Benutzern des Service ein Konzept, dass solche häßlichen Effekte verhindert.

getFeatureInfo

Sich Karten einfach nur anzusehen, ist selbstverständlich nur die Hälfte des Reizes eines WMS-konformen Servers. Man möchte selbstverständlich auch Queries auf die Daten durchführen können. Zu diesem Zweck gibt es den =REQUEST= mit dem Namen =getFeatureInfo= .

Zuerst einmal gilt es, Queries überhaupt erst einmal zuzulassen. Wie schon bei den 'klassischen' Queries (siehe Abschnitt~\ref{text:mapfile:queries}) kann man in MapServer eine Query nur auf einem Layer durchführen, der ein =TEMPLATE= definiert.

Wenn man das tut, und sich die capabilities anschaut, wird man für den Layer auf ein Attribut der folgenden Art treffen:


<Layer queryable="1" opaque="0" cascaded="0">

Der Wert =1= für =queryable= zeigt im Gegensatz zum Wert =0= an, dass Queries auf diesen Layer zulässig sind.

Um einen Aufruf vom Typ =getFeatureInfo= zu verstehen, betrachten wir einmal einen vollständigen URL für diesen Vorgang:


http://www.example.com/cgi-bin/mapserv

    ? map=/usr/local/mapserv/mapfile.map
    & VERSION=1.1.0
    & REQUEST=getFeatureInfo
    & QUERY_LAYERS=gruenflaechen
    & SRS=EPSG:4326
    & BBOX=5.0,45.0,15.0,55.0
    & WIDTH=500
    & HEIGHT=500
    & X=250
    & Y=250
    & INFO_TYPE=text/plain


Einige Bestandteile sind dem Leser bereits bekannt: Version des Standards, Angabe der Projektion durch =SRS= . Dazu kommt, wenig überraschend, die Angabe des =REQUEST= .

Da jetzt keine Darstellung mehr erfolgen sollen, werden keine =LAYERS= mehr angegeben, sondern =QUERY_LAYERS= \footnote{Diese Unterscheidung ist offensichtlich eigentlich unnötig, da man die Funktion der Layerangabe ja eigentlich serverseitig aus dem =REQUEST= schließen könnte.}. Um Ergebnisse zu liefern, muß jeder Layer in der Liste =QUERY_LAYERS= das Attribut =queryable= auf =1= gesetzt haben -- siehe oben.

Zwingend sind darüberhinaus die Angabe der Extents des Bildes, das man befragen möchte (angegeben mit =BBOX= ), Breite und Höhe des Bildes sowie die X- und die Y-Koordinate des Punktes im Bild, der sich der Aufmerksamkeit des Users erfreut, beispielsweise durch einen Mausklick. Beachten Sie, dass es sich dabei um Bildkoordinaten handelt, es handelt sich also um Pixelwerte. Der Koordinatenursprung eines Bildes ist links oben.

Am interessantesten ist natürlich der =INFO_TYPE= , der angibt, auf welche Weise die Queryergebnisse formatiert sein sollen. MapServer unterstützt die folgenden Formate:


  • =text/plain= , das Standardformat, falls Sie nichts anderes angegeben haben;
  • =text/html= , was ein wenig Vorbereitung erfordert, im wesentlichen aber wie Queries auf einem 'normalen' MapServer-CGI behandelt wird; und
  • =application/vnd.ogc.gml= , GML, eine XML-Repräsentation für Geodaten.

Betrachten wir die Formate im Detail:

\subsubsection*{text/plain}

Dieser Ausgabetyp für getFeatureInfo ist die Voreinstellung für MapServer, falls Sie keinen anderen Ausgabentyp spezifizieren.

Für ein Mapfile mit den Voreinstellungen des Itasca-Demos und einem fiktiven Anklickpunkt mit den Koordinaten 200/200 sieht die Ausgabe folgendermaßen aus:


GetFeatureInfo results:

Layer 'countyboundary'

 Feature 26: 
   AREA = '7577272785.15393'
   PERIMETER = '436617.07762'
   CTY_NAME = 'Itasca'
   COUN = '31'
   CTY_ABBR = 'ITAS'
   ISLAND = 'N'
   CTY_FIPS = '61'
   RECNO = '27'


Es wird der Name des Layers ausgegeben, die Nummer des Layers innerhalb des Shapefiles, und dann alle Attribute aus der =.dbf= -Datei der Datei. Wenn es mehrere Suchergebnisse gegeben hat, werden diese der Reihe nach dargestellt.

\subsubsection*{text/html}

Mit diesem Ergebnistyp greift MapServer auf die HTML-Templates zurück, die Sie für Queries bereits in Kapitel~\ref{text:mapfile} kennengelernt haben. Das bedeutet, dass Sie ein HTML-Layout ganz nach Ihrem Geschmack gestalten können, und MapServer die entsprechenden Tags in eckigen Klammer wie gewohnt ersetzt.

Dieser MIME type bietet jedoch noch die Möglichkeit für zusätzliche Tricksereien. Der Standard schreibt nämlich keinen MIME type zwingend vor, und ebensowenig gibt es ein vorgeschriebenes Verhalten für den Fall, dass ein bestimmter Typ nicht unterstützt wird. Das führt dazu, dass MapServer es sich vorbehält, beliebige Arten von Daten zurückzuliefern.

Sie können ein =TEMPLATE= definieren, das nicht gezwungenermaßen eine HTML-Seite sein muß. Reiner ASCII-Text wäre ebenso möglich, oder alle anderen Formate, in denen Sie MapServer-Tags ersetzen können.

Sobald das Template beliebigen Formats von MapServer bearbeitet worden ist, kann das Resultat zurückgeliefert werden. Wenn man jetzt reinen ASCII-Text hat, würde MapServer ihn jedoch als =text/html= ausliefern, und das ist eigentlich nicht das, was man möchte. Der Client (also z.B. Webbrowser) interpretiert die Daten natürlich nur korrekt, wenn man ihm den korrekten MIME type liefert. Daher kann man im Mapfile für die zurückgegebenen Daten einen eigenen Metadatum den geeigneten Typ setzen:


WEB

 ...
 METADATA
   ...

"wms_feature_info_mime_type" "text/plain"

 END

END

Also noch einmal zusammenfassend: der Benutzer kann zwar von außen den =INFO_TYPE= auf =text/html= setzen; MapServer kann jedoch mit Daten beliebigen Typs antworten.

\subsubsection*{application/vnd.ogc.gml}

Damit ein Layer in diesem Format Anfragen beantworten kann, muß außerdem der Parameter =DUMP= in diesem Layer gesetzt sein:


LAYER

...
DUMP TRUE

END

Falls es keine Suchresultate gegeben hat, wird zwar eine Datei im korrekten Format zurückgegeben, die allerdings nur die korrekten Header enthält und ansonsten leer ist.

Für Suchergebnisse werden in diesem Format immer die Koordinaten des Features gleich mitgeliefert. Antworten können also bei großen Features nicht nur auf sich warten lassen, da MapServer für das Erzeugen großer Dokumente natürlich eine Weile braucht, sondern auch weil der Transfer über das Netz natürlich ein bißchen dauert.

Die Anfrage auf den Flughafen-Layer der Itasca-Demodaten beispielsweise liefert in den voreingestellten Extents und dem fiktiven Klick auf die Koordinate 224/75 das folgende Ergebnis:


<?xml version="1.0" encoding="ISO-8859-1"?>

<msGMLOutput

xmlns:gml="http://www.opengis.net/gml"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance">

<countyboundary_layer>

 <countyboundary_feature>
   <AREA>7577272785.15393</AREA>
   <PERIMETER>436617.07762</PERIMETER>
   <CTY_NAME>Itasca</CTY_NAME>
   <COUN>31</COUN>
   <CTY_ABBR>ITAS</CTY_ABBR>
   <ISLAND>N</ISLAND>
   <CTY_FIPS>61</CTY_FIPS>
   <RECNO>27</RECNO>
   <gml:boundedBy>
     <gml:Box srsName="EPSG:26915">
       <gml:coordinates>
         393234.393701,5207990.085063
         495769.579719,5305374.105135
       </gml:coordinates>
     </gml:Box>
   </gml:boundedBy>
   <gml:Polygon srsName="EPSG:26915">
     <gml:outerBoundaryIs>
       <gml:LinearRing>
         <gml:coordinates>
           393865.671855,5300138.258409
           393869.171975,5300138.258374 
           394516.694141,5300137.439369 
           395522.728579,5300136.241770 
           [...]


Und so weiter, mit allen Punkten des Features.

==WMS Clients==\index{OGC!Client}(6)

WMS-konforme Mapserver lassen sich kaskadieren, indem einzelne Layer einfach als fertige Bilder von anderen WMS-konformen Mapservern bezogen werden. Durch die standardisierte Schnittstelle ist dafür kein UMN MapServer nötig. Sie können einzelne Layer beispielsweise auch von einem ESRI ArcIMS beziehen, wenn Sie möchten.

Neben der schönen Möglichkeit, die Standorte und somit Pflege einzelner Teile der Kartenerzeugung voneinander trennen zu können, indem man beispielsweise die Bodenproben von einem Amt und die hydrogeologischen Karten von einem anderen Amt miteinander über eine genormte Schnittstelle verbindet, ist ein weiteres offensichtliches Einsatzfeld natürlich die Lastenverteilung. Datenbestände, die erst umprojiziert werden müssen, können auf leistungsfähigere Server ausgelagert werden, während einfache Operationen wie beispielsweise die simple Darstellung von Rasterbildern von schwächeren Geräten übernommen werden kann\footnote{Beachten Sie dabei immer, dass zur Erzeugung des fertigen Bildes immer auf den langsamsten Layer gewartet werden muß, da ja das Bild ansonsten nicht komplett ist.}.

Im folgenden soll betrachtet werden, wie Sie einen Layer in einem Mapfile erstellen, damit er dynamisch Daten von einem WMS-konformen Server bezieht. Nach außen hin verhält sich dieser Layer dann wie jeder andere Rasterlayer auch.

\subsubsection*{Installation und Konfiguration}

Wie weiter hinten im Kapitel 'Installation' ab Seite~\pageref{text:installation} beschrieben, ist die Fähigkeit, als WMS-Client zu fungieren, nicht als Voreinstellung bei der Kompilierung gegeben, sondern muß explizit angefordert werden. Wie das genau gemacht wird, und welche Voraussetzungen gegeben sein müssen, ist in Abschnitt~\ref{text:installation:compile:wmsclient} erklärt.

\subsubsection*{getMap}

Der erste Schritt ist, sicherzustellen, dass der anzusprechende Server funktioniert und die gewünschten Daten ausliefert. Dafür holt man sich das Capabilites-Dokument dieses Servers. Wie das zu tun ist, ist auf Seite~\pageref{text:wms:getcapabilities} beschrieben.

Nun weiß man alles über die Fähigkeiten des Servers (welche Projektionen angeboten werden, wie seine Layer heißen und so weiter) und kann sich darum kümmern, eine erste Karte zu holen, um zu sehen, ob die Darstellung dem entspricht, was man erwartet. Dazu richtet man mit seinem Webbrowser eine =getMap= -Anfrage an den Server.

Wie so eine Anfrage aufgebaut sein muß, wurde bereits in Abschnitt~3 gezeigt. Ersetzen Sie allerdings alle Werte für die Parameter durch diejenigen, die Sie im abgerufenen Capabilities-Dokument gefunden haben, also durch korrekte Projektionen, Layernamen, Extents und so weiter. Sobald dieser Aufruf eine Karte in Ihrem Browser zaubert, wissen Sie, dass Sie gültige Werte besitzen und sie korrekt notiert haben, sodass Sie diese Angaben jetzt in einen Layer in Ihr Mapfile einbauen können.

\subsubsection*{Das Mapfile}

Zunächst benötigen Sie einen =PROJECTION= -Block für Ihre Karte. Sie können auf diesen Block verzichten, wenn alle Layer in der gleichen Projektion vorliegen und auch die von Ihnen angesprochenen WMS-Server nur diese eine Projektion unterstützen.

Beachten Sie, dass Sie in der =WEB= -Sektion Ihres Mapfiles einen =IMAGEPATH= -Parameter benötigen, da die Bilder von entfernten Servern als temporäre Dateien gespeichert werden müssen. Diese temporären Dateien werden übrigens nach Verwendung gleich wieder gelöscht, sodass Sie sie kaum bemerken werden.

Für WMS-konforme Anfragen an andere Server sind lediglich die Layerdefinitionen anzupassen. Dabei kommt ein =CONNECTIONTYPE= mit dem Namen =WMS= zum Einsatz:


LAYER

 NAME "Gewaesser"
 TYPE RASTER
 STATUS ON
 CONNECTIONTYPE WMS
 CONNECTION "http://www.example.com/cgi-bin/mapserv?"
 METADATA
   "wms_title"          "Gewaesser"
   "wms_server_version" "1.1.0"
   "wms_srs"            "EPSG:4326 EPSG:31464"
   "wms_name"           "seen,kanaele,fluesse,baeche"
   "wms_format"         "image/png"
 END
 PROJECTION
   "init=epsg:31464"
 END

END

Wie Sie sehen, ist der URL selber sehr kurz gehalten. Er entspricht der onlineresource aus dem Capabilities-Dokument eines WMS-konformen Servers.

Alle weiteren Details zur Verbindung mit dem entfernten Server werden in Form von Metadaten gemacht. Wer bisher MapServer 3.6 eingesetzt hat, wird das noch anders kennen: in jener Version wurde noch der gesamte Verbindungsstring (bis auf die dynamischen Elemente) in der =CONNECTION= notiert.

Der =wms_title= ist der Titel für diesen Layer, der mit der Anfrage allerdings nichts zu schaffen hat.

Die Version der Anfrage wird mit =wms_server_version= notiert. Mit =wms_srs= geben Sie wieder Projektionen an, allerdings diejenigen, die von der Gegenstelle unterstützt werden.

=wms_name= benennt den oder die Layer, aus denen die bezogene Karte zusammengesetzt werden soll. Mehrere Layer werden durch Kommata voneinander abgetrennt. Beachten Sie, dass bei WMS die Reihenfolge der Ebenen von Belang ist: in unserem Beispiel werden zuerst der Layer =seen= gezeichnet, darauf dann =kanaele= und so weiter.

Das gewünschte Bildformat wird schließlich mit =wms_format= spezifiziert. Es gibt auch den Parameter =wms_formatlist= , der mehrere durch Kommata getrennte Angaben zuläßt.

Wichtiger Hinweis : An keiner einzigen Stelle lädt sich MapServer die Capabilities des entfernten Servers herunter, um sich mit ihnen auseinanderzusetzen. Sie müssen also selber darauf achten, dass die von Ihnen gemachten Angaben stimmig sind.

Exceptions

Wenn Sie einen Layer haben, der sich Daten von einem WMS-konformen Server holt, drängt sich natürlich die Frage auf, wie MapServer im Fall von Exceptions reagiert. Eindeutige Antwort: das kommt drauf an.

Am einfachsten ist es offensichtlich, mit Exceptions, die direkt im Bild eingefügt sind, umzugehen, also mit denen, die vom Typ =application/vnd.ogc.se_inimage= sind. Diese werden einfach Bestandteil der fertigen Karte, die Sie im Webbrowser sehen. Im Fehlerfall bemerkt sehr schnell, was Sache ist.

Das gleiche gilt offensichtlich bei =application/vnd.ogc.se_blank= .

Liefert die Gegenstelle ein textbasiertes Format, also zum Beispiel GML zurück, dann gibt es ein Problem, da MapServer davon ausgeht, dass er Rasterdaten als Input erhält; demnach versucht er, das GML-Dokument als Text zu rendern, was natürlich schief geht und somit eine Fehlermeldung erzeugt.

Dieses Problem läßt sich bisher leider auch noch nicht umgehen. Das mindeste, was man also tun kann, ist für eine funktionierende Kommunikation mit dem Betreiber des Quellservers zu sorgen, damit dieser nicht einfach unangekündigt Layernamen ändert, die Ihnen Ihre Applikation wegbrechen lassen.

==Hinweise==(7)

FIXME: das auch noch bei WFS erwähnen

Wenn Sie mit der Administration sowohl des Mapservers, der als Client fungiert, als auch der Serverseite betraut sind, sollten Sie auf alle Fälle darauf achten, keine zirkulären Bezüge zu erzeugen, bei denen Server A einen Layer von Server B bezieht und dieser dann wieder Server A aufruft. Bei komplexen Installationen ist das durchaus eine Fehlerquelle, das Verhalten in diesem Fall ist undefiniert.

Ein weiterer wichtiger Faktor beim Einsatz von WMS-konformer Funktionalität ist die unschöne Tatsache, dass MapServer das Sammeln der Daten für einzelne Layer linear abarbeitet, und nicht mit einem einzelnen Thread oder Prozess pro Layer arbeitet. Das bedeutet, dass MapServer genau gar nichts tut, während er auf einen Layer aus dem Netzwerk wartet, um dann zum nächsten Layer überzugehen\ldots der dann vielleicht wieder ein solcher Layer ist, oder eine Datenbankquelle. Es wird also unnötig Rechenzeit vergeudet. Dieses Problem läßt sich im Moment auch leider nicht umgehen.

\subsubsection*{Weitere Modi für WMS}

Wer den Standard aufmerksam liest, wird noch vier weitere Operationsmodi finden, die in den einführenden Zeilen zu diesem Abschnitt nicht genannt worden sind. Sie umfassen:


  • =describeLayer=
  • =getLegendGraphic=
  • =getStyles=
  • =putStyles=

Diese Modi sind nur für Mapserver von Relevanz, die den OGC-Standard SLD unterstützen. Mit diesen styled layer descriptor ist es möglich, von außen Einfluß auf die ansonsten fixe Kartengestaltung eines Mapservers zu nehmen. Da dieser Standard serverseitig von MapServer bisher nicht unterstützt wird\footnote{Und clientseitig nur sehr sporadisch; konsultieren Sie hierzu bitte die Online-Dokumentation.}, findet hier keine detaillierte Beschreibung statt. Sie können sich aber selbstverständlich den Standard~pdf:spec:sld10 lesen.

=Web Feature Server (WFS)=(8)

Die entsprechende Spezifikation des OGC~pdf:spec:wfs100 sieht WFS im Kontext zu WMS. Nach der Formulierung in der Einführung des Dokuments ist WFS der 'nächste logische Schritt' nach WMS. Wo WMS die Möglichkeit bietet, Capabilities abzufragen Karten anzuzeigen und schließlich Anfragen bezüglich der Datengrundlage der Karten zu machen, stellt WFS ein Interface zur Verfügung, dass es dem Benutzer ermöglicht, Einfluß auf die Datengrundlage zu nehmen, indem Features in der Karte geändert und gelöscht, bzw. neue Features hinzugefügt werden können.

Das hört sich alles ziemlich gut an -- und doch muß der begeisterte Leser hier enttäuscht werden. MapServer ist bisher ausschließlich darauf ausgelegt, Daten aus Quellen wie der Festplatte oder einer Datenbank zu lesen und Karten zu produzieren. Von einer Unterstützung für Datenänderungen ist man im Moment noch sehr weit entfernt -- falls sie überhaupt kommen wird\footnote{Es besteht natürlich die Möglichkeit, dass Sie beispielsweise mit MapScript entsprechende Fähigkeiten in einer eigenen Applikation programmieren. Stellen Sie sich auf einigen Aufwand ein.}.

Was wir mit MapServer kriegen, ist allerdings zumindest die Möglichkeit, Vektorlayer über den Transportmechanismus von WFS als Server auszuliefern bzw. als Client zu beziehen. Das funktioniert nur mit Vektordaten, da sich Rasterdaten offensichtlich nicht in das XML-Format mit dem Namen GML verpacken lassen. Diese Geography Markup Language ist selbstverständlich ebenfalls in einer eigenen Implementation Specification definiert~pdf:spec:gml.

Von den in der Spezifikation definierten Anfragetypen sind im MapServer die folgenden implementiert:


  • =getCapabilities= , um ein Capabilities-Dokument abrufen zu können, wie man es bereits von WMS kennt.
  • =describeFeature= liefert eine Beschreibung eines Features zurück.
  • =getFeature= holt eine GML-Repräsentation eines Features.

WFS Server

Wie schon beim WMS-konformen Server, wird WFS in MapServer dadurch aktiviert, dass die notwendigen =METADATA= -Tags in das Mapfile eingefügt werden. Zuerst einmal müssen aber die folgenden Vorkehrungen getroffen werden:


  • Zuerst muß MapServer natürlich mit WFS-Unterstützung kompiliert worden sein. Detaillierte Vorgaben dafür finden Sie in Anhang~\ref{anhang:compile}.
  • Das Mapfile muß einen =NAME= haben, ebenso wie jeder einzelne Layer. Wie schon bei WMS geht MapServer bei WFS davon aus, dass jeder Layer, der sich im Mapfile befindet, auch über WFS zur Verfügung gestellt werden soll.

MapServer kann ausschließlich Vektorlayer in seinen WFS-Capabilites erscheinen lassen, also Shapefiles, PostGIS-Layer und so weiter; der Typ des Layers muß also =POINT= , =LINE= oder =POLYGON= sein.

Desweiteren muß die Eigenschaft =DUMP= im Layer auf =TRUE= gesetzt sein. Dies zeigt MapServer an, dass er GML-Repräsentationen für diesen Layer erzeugen darf. Das entspricht der Vorgabe, =getFeatureInfo= mit einem WMS-konformen Server nutzen zu können.

In der =WEB= -Sektion des Mapfiles müssen dann die folgenden Angaben gemacht werden.


  • =wfs_onlineresource= Die Basisadresse des Servers. Hat denselben Aufbau wie der gleichnamige Parameter für WMS. Allerdings muß man einem WFS-konformen MapServer noch mitteilen, wie er WFS- von WMS- Anfragen zu unterscheiden hat. Das geschieht durch =SERVICE= , also etwa derart:
    WEB .. METADATA ... "wfs_onlineresource" \ "http://www.example.com/cgi-bin/mapserv?SERVICE=WFS&map=..." END END
    Diese Angabe ist auch dann nötig, wenn der MapServer nicht darauf eingerichtet oder konfiguriert ist, als WMS-Server zu fungieren.
  • =wfs_title= Titel für die Karte; siehe WMS-Konformität. Zwingend notwendig.
  • =wfs_abstract= Eine elaborierte Zusammenfassung über Sinn und Zweck dieses Servers. Siehe WMS-Konformität.
  • =wfs_keywordlist= Eine Liste mit Schlüsselworten, die einen Bezug zu diesem WFS-Server haben. Siehe WMS-Konformität.
  • =wfs_accessconstraints= Beschränkungen, die den Zugriff auf diesen Server betreffen. Siehe WMS-Konformität.
  • =wfs_fees= Gebühren, die beim Zugriff auf diesen Server anfallen. Siehe WMS-Konformität.
  • =wfs_encoding= Die Kodierung für die XML-Dateien, die durch den WFS-Server ausgeliefert werden. Voreingestellt ist hier ISO-8859-1.
  • =ows_schema_location= Der Ort, an dem die OWS-Schemas zur Validierung der generierten XML-Dateien liegen. Siehe weiter unten auf Seite~\pageref{text:wfs:schemas}.
  • =wfs_geometry_element_name= Weiter unten gibt es ein Beispiel zu sehen, wie eine Datei aussehen kann, die von einem WFS-konformen MapServer ausgeliefert wird. Das Element, dass die Liste der Koordinaten eines Features umfaßt, hat dabei keinen fixen Namen. Sie können mit diesem Parameter hier einen Namen festlegen; Voreinstellung in MapServer ist =MS_GEOMETRY= .
  • =wfs_srs= Die Projektion, die für alle Layer in der Karte gelten soll. Wird als EPSG-Code angegeben und genauso wie bei WMS-konformen Servern notiert. Beachten Sie bitte die Anmerkungen zu Projektionen in WFS-konformen Servern im nächsten Abschnitt.

Beachten Sie, dass diese Parameter im Gegensatz zu den WMS-Parametern alle den Präfix =wfs_= tragen. Einzige Ausnahme ist =ows_schema_location= .

Projektionen in WFS-Servern

Die WFS-Spezifikation macht zu Projektionen andere Vorgaben als idie für WMS. So können einzelne Layer nicht in mehr als einer Projektion ausgeliefert werden. Es gibt auch keine Projektionsangabe, die man ein einziges Mal für alle Layer machen kann\footnote{Man kann aber, wie Sie weiter oben sehen konnten, MapServer so konfigurieren, dass er einen SRS-Eintrag in der WEB-Sektion bekommt und diesen dann auf alle Layer überträgt.}. Es ist aber sehr wohl möglich, für jeden Layer eine unterschiedliche Projektion anzubieten. Außerdem nennt der Standard keine Default-Projektion; anders als bei WMS, wo mindestens =EPSG:4326= angeboten werden muß.

MapServer entscheidet in zwei Schritten, welche Projektion für einen Layer nach außen mitgeteilt wird. Wenn es eine 'übergeordnete' Projektion gibt (also einen Projektionsblock mit EPSG-Code für die ganze Karte, bzw. ein =wfs_srs= in der WEB-Sektion), so findet diese Projektion auf alle Layer Anwendung, selbst dann, wenn die Layer selber noch einmal über =wfs_srs= eine Projektion definieren.

Gibt es keine solche 'Überprojektion', muß jeder Layer einen eigenen Wert setzen.

==Schemas==(9)

Schemas\footnote{In diesem Fall nicht Schemata, da es sich um einen feststehenden englischen Begriff handelt.} sind ein Mechanismus, XML-Dateien zu validieren, also zu prüfen, ob sie einem bestimmten Aufbau genügen. Sie können ein Paket standardkonformer Schemas von~http:owssamples herunterladen.

Das Archiv entpacken Sie an einen Ort, der für den WebServer erreichbar ist. Danach können Sie, wie oben gesehen, mit einem entsprechenden Metadatum den Pfad zu den Schemas angeben:


WEB

 ...
 METADATA
  ...
  "ows_schema_location" "/pfad/zu/den/schemas"
 END

END

Geben Sie keinen Pfad an, wird =..= als Ort für die Schemas angenommen. Der Gedanke hinter dieser Entscheidung war, dass man damit im Wurzelverzeichnis des Webservers landet, wenn man sein MapServer-Binary im Verzeichnis =cgi-bin/= hat\footnote{Eine sehr Apache-zentrierte Denkweise.}.

Der Präfix =ows_= zeigt übrigens an, dass hier auf mehr als nur WFS-Schemas verwiesen wird; vielmehr handelt es sich um einen Verweis auf Schemas, die sich auf OGC Web Services beziehen.

Aufruf \& Capabilities

Sobald man die ganze vorbereitende Arbeit hinter sich gebracht hat, kann man prüfen, ob alles korrekt eingerichtet worden ist. Dazu richtet man, wie schon beim WMS-konformen Server, eine Anfrage vom Typ =getCapabilities= an den Server:


http://www.example.com/cgi-bin/mapserv

 ? SERVICE=WFS
 & REQUEST=getCapabilities
 & map=...


Die Vorgehensweise entspricht jetzt haargenau dem, was Sie auch mit einem WMS-Server tun würden: Sie durchsuchen das Capabilites-Dokument nach Warnungen und Fehlern, und wenn sich alles so verhält, wie es geplant war, dann haben Sie einen einsatzfähigen, WFS-konformen Server.

WFS Client

Was man mit WMS machen kann, will man selbstverständlich auch mit WFS machen: Einbinden von WFS-Layern als eigene Kartenebenen. Die Vorgehensweise ist dabei stark an eben das Einfügen von WMS-Layern angelehnt.

FIXME: blah

Die Voraussetzungen für die Kompilierung eines WFS-konformen Client sind etwas umfänglicher als für den entsprechenden Server. Sieh auch Abschnitt [FIXME] im Anhang.

Ein WFS-Client-Layer ist sieht anders aus als ein 'normaler' Layer, hat aber Ähnlichkeit mit einem WMS-konformen Layer. Hier ein Beispiel:


LAYER END

FIXME: vervollständigen!1!

Map Context

Diese Spezifikation ist eine Ergänzung zur WMS-Spezifikation. Sie beschreibt einen Mechanismus, mit dem Informationen über eine Menge von WMS-produzierten Layern auf eine portable Weise zwischen Systemen ausgetauscht bzw. in einem definierten Format gespeichert und abgerufen werden können.

Das Dokument, das diesen Standard definiert ist in der Version 1.0 von der OGC-Website herunterladbar~pdf:spec:mapcontext10.

MapServer kann Kontextdokumente in den Versionen 0.1.2, 0.1.4, 0.1.7 und 1.0 lesen, und in den Versionen 0.1.4, 0.1.7 und 1.0 exportieren.

Kontextdokumente lassen sich im MapServer darüberhinaus nur in MapScript verwenden, und selbst dort nur in der PHP-Fassung. Alles andere wird (noch?) nicht unterstützt. Darüberhinaus geht Map Context davon aus, dass die WMS-Spezifikation 1.1.1 beachtet wird.

Notwendige Bibliotheken für die Map Context-Funktionalität sind die Projektionsbibliothek proj.4, GDAL/OGR im Zusammenspiel mit Xerces sowie PHP MapScript. Genaue Installationsanleitungen für diese Komponenten finden Sie im Anhang ab Seite~\pageref{text:installation}.

Das Context-Dokument

Der Inhalt eines Context-Dokuments (oder schlicht: eines Contexts) besteht im wesentlichen aus Angaben über die Quelle(n) der einzelnen Layer, die verwendeten Bounding Boxes, Projektionen und eventuell diverse Metadaten.

Wie bei praktisch allem, was mit dem OGC in Zusammenhang steht, ist der Context ein XML-Dokument. Beachten Sie, dass in einem Context-Dokument tatsächlich nur WMS-Layer gespeichert werden können.

FIXME: fertig!1!

Den Kontext verwenden

Dieser Abschnitt sollte sinnvoller eigentlich im Kapitel über PHP MapScript erscheinen; der Konsistenz halber ist er hierher gewandert. Denn wie bereits erwähnt, kann Map Context bisher nur im Zusammenspiel mit PHP-MapScript benutzt werden.

Wenn Sie ein Mapfile nach den obigen Vorgaben erstellt haben, können Sie testen, ob Sie alles richtig gemacht haben:


<?php

 dl ("php_mapscript40.so");
 <math>map = ms_newMapObj ("mapfile.map");
 </math>map -> saveMapContext ("mapfile_context.xml");


Danach geht es nach dem bewährten Muster daran, in der fertigen XML-Datei nach Warnhinweisen zu suchen, die zeigen, dass Dinge fehlen oder Fehler vorliegen. Wenn das nicht mehr passiert, kann Ihr Mapfile als Quelle für einen Map Context dienen.

FIXME: fertig!1!